乐闻世界logo
搜索文章和话题

前端面试题手册

什么是"use strict";?使用它有什么优缺点?​

什么是"use strict"?"use strict"; 是一个JavaScript中的指令,也称作严格模式(strict mode),它用于将整个脚本或单个函数置于一个更加严格的操作环境中。当在代码的开始处使用该指令时,它有助于捕获一些常见的编程错误,同时防止或抛出错误,以及在某些情况下提高编译器的优化水平。由于这些原因,它会改善代码的运行速度和效率。使用它有什么优点?提前捕获错误: 严格模式会在代码执行前就发现一些错误,这些在非严格模式下可能不会被检测到。例如,对不可写的属性赋值,或对只读属性(如undefined,NaN)赋值。避免意外的全局变量: 在严格模式下,如果不使用var、let或const来声明变量,将会抛出错误,这样可以避免全局变量的隐式声明,减少代码中的潜在错误。消除this的混乱: 在严格模式下,如果没有指定上下文对象,函数内的this值将是undefined,这比默认指向全局对象要安全。更安全的eval: 严格模式下,eval函数内部声明的变量不会影响到外部作用域,这使得eval的使用更加安全。提高编译器优化: 代码在执行之前可以进行更多的检查,这为JavaScript引擎的优化打下基础,可能会提高执行速度。使用它有什么缺点?兼容性问题: 在老旧的浏览器或JavaScript环境中,可能不支持严格模式,或者其行为与新版的解释器不一致。代码修改成本: 如果要在已有项目中引入严格模式,可能需要对现有代码进行较大范围的修改,以确保兼容性和正确性。学习曲线: 对于初学者来说,严格模式下的某些限制可能会增加学习难度,因为它们需要更好地理解JavaScript的工作原理。可能隐藏的问题: 在非严格模式写的代码中可能含有在严格模式中会失败的部分,如果不进行彻底的测试,这些隐藏的问题在切换到严格模式后可能会导致运行时错误。示例:以下是一个简单的例子,展示了在使用严格模式时变量必须声明,否则会抛出错误:"use strict";function myFunction() { undeclaredVariable = 123; // 这里会抛出错误,因为变量没有声明}myFunction();如果没有"use strict"; 指令,上面的代码中的undeclaredVariable会被创建为一个全局变量,这可能是一个潜在的问题。使用严格模式,我们可以避免这种情况。
阅读 115·2024年8月5日 12:43

bind、call、apply 的区别

bind、call和apply都是JavaScript中的函数对象的方法,它们都可以用来改变函数的this指向。每个方法的使用场景和方式有所不同:callcall方法可以让我们在调用一个函数的同时,指定函数内部this的值,也就是改变函数运行时的上下文。call的第一个参数是this要指向的对象,其余参数依次传入。例子:function introduce(name, age) { console.log(`My name is ${name}, and I am ${age} years old. I work as a ${this.job}.`);}const person = { job: 'developer'};introduce.call(person, 'Alice', 30); // 输出:My name is Alice, and I am 30 years old. I work as a developer.在以上例子中,我们使用call将introduce函数内部的this绑定到person对象,同时传入了name和age作为参数。applyapply方法与call非常相似,区别在于apply传入参数的方式。apply的第一个参数同样是this的值,但第二个参数是一个数组,数组中包含了所有传给函数的参数。例子:function introduce(name, age) { console.log(`My name is ${name}, and I am ${age} years old. I work as a ${this.job}.`);}const person = { job: 'developer'};introduce.apply(person, ['Alice', 30]); // 输出:My name is Alice, and I am 30 years old. I work as a developer.在这个例子中,apply被用来将introduce函数的this绑定到person对象,参数以数组形式传入。bindbind方法创建一个新的函数,可以在稍后时间里执行,它允许我们绑定this及初始参数。与call和apply不同,bind并不立即执行函数,而是返回一个改变了上下文this后的新函数。例子:function introduce(name, age) { console.log(`My name is ${name}, and I am ${age} years old. I work as a ${this.job}.`);}const person = { job: 'developer'};const boundIntroduce = introduce.bind(person, 'Alice', 30);boundIntroduce(); // 输出:My name is Alice, and I am 30 years old. I work as a developer.在这里,bind被用来创建了一个新的introduce函数,该函数的this被永久绑定到person对象。总结:call和apply都是立即调用函数,但是参数传递方式不同;call将参数按顺序传递,而apply则是传入参数数组。而bind则是返回一个新的函数,可以在以后任何时间点调用,其this值和参数都已经预设好了。
阅读 109·2024年7月28日 17:16

Vue组件之间通信方式有哪些

在Vue.js中,组件之间的通信是一个非常重要的话题,因为它关系到应用程序如何将数据和事件在多个组件之间传递。Vue提供了多种组件通信的方式,适用于不同的场景。下面是一些常见的通信方式:1. Props 和 Events这是最基本也是最常用的组件间通信方式。父组件通过props向子组件传递数据,子组件通过事件向父组件发送消息。例子:在父组件中:<template> <Child :parentData="data" @childEvent="handleEvent"/></template><script>import Child from './Child.vue';export default { components: { Child }, data() { return { data: 'data from parent', }; }, methods: { handleEvent(payload) { console.log('Event received from child:', payload); }, },};</script>在子组件中:<template> <button @click="sendToParent">Send to Parent</button></template><script>export default { props: ['parentData'], methods: { sendToParent() { this.$emit('childEvent', 'data from child'); }, },};</script>2. Event BusEvent bus 是一种使用Vue实例作为中央事件总线的方法,在不直接关联的组件之间传递消息。例子:// eventBus.jsimport Vue from 'vue';export const EventBus = new Vue();在发送事件的组件中:import { EventBus } from './eventBus.js';export default { methods: { sendEvent() { EventBus.$emit('do-something', 'some data'); }, },};在接收事件的组件中:import { EventBus } from './eventBus.js';export default { created() { EventBus.$on('do-something', data => { console.log(data); }); },};3. VuexVuex是Vue.js的状态管理库,可以用来管理所有组件的共享状态,是一种全局的通信方式。例子:// store.jsimport Vue from 'vue';import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({ state: { message: '', }, mutations: { updateMessage(state, message) { state.message = message; }, },});在一个组件中更新状态:<template> <button @click="update">Update Message</button></template><script>import { mapMutations } from 'vuex';export default { methods: { ...mapMutations([ 'updateMessage', // 映射 this.updateMessage() 为 this.$store.commit('updateMessage') ]), update() { this.updateMessage('Hello from Component A'); }, },};</script>在另一个组件中获取状态:<template> <div>{{ message }}</div></template><script>import { mapState } from 'vuex';export default { computed: { ...mapState([ 'message', // 映射 this.message 为 this.$store.state.message ]), },};</script>4. Provide / Inject这是一种在更深层次的嵌套组件中传递数据的方法,不需要通过每个组件层次传递props。例子:在祖先组件中:<script>export default { provide() { return { theme: 'dark', }; },};</script>在任意后代组件中:<script>export default { inject: ['theme'], mounted() { console.log(this.theme); // 输出: 'dark' },};</script>这些通信方式各有优缺点,适用于不同的场景和需求,通常在实际开发中需要根据应用的具体需求来选择合适的通信方式。
阅读 137·2024年7月4日 09:37

什么是同源策略?什么是跨域问题?有什么手段可以解决跨域问题?

同源策略同源策略是一种对浏览器发出请求的安全策略。根据这种策略,一个Web页面只能从同一来源(协议,域名和端口都必须相同)获取数据。跨域问题.当一个Web页面尝试从不同的源访问资源时,就会出现跨域问题。例如,一个在 www.example1.com 上托管的脚本尝试访问 www.example2.com 上的资源,这就违反了同源策略,所以浏览器会阻止这个请求并产生跨域错误。解决跨域问题的手段以下是一些常见的解决跨域问题的方法:CORS(跨源资源共享):CORS是一种让服务器允许来自特定源访问资源的机制。服务器通过设置特定的HTTP头部告诉浏览器哪些Web页面可以访问这些资源。JSONP(JSON with Padding):JSONP是一种通常用于解决跨域数据获取问题的方式。不过,这种方式局限于GET请求,并且安全性较差。代理服务器:可以使用服务器端的代理转发请求,因为在服务器端不受同源策略限制。postMessage API:使用HTML5引入的 window.postMessage 方法,可以安全地实现跨源通信。WebSocket协议:WebSocket是一种建立在TCP协议之上的全双工通信协议,不受同源策略影响。WebSockets:WebSockets API 是另一种通信协议,它不受同源策略的影响,可以用于任何地方的通信。Document.domain+iframe:基于 document.domain 的跨域方法只适合主域相同的情况,也就是abc.example.com到www.example.com这样的跨域,区域子域和顶级字段相同。
阅读 103·2024年6月24日 16:43

Web前端安全攻击手段有哪些?以及应该如何做相应的防御措施?

Web前端安全攻击主要有以下几种常见的方式:XSS攻击(跨站脚本攻击):攻击者通过在目标网站上注入恶意的HTML代码,当用户浏览该网站时就会运行这些恶意代码。防御措施:输入验证与过滤、输出编码、使用CSP(内容安全策略)防止不安全的动态脚本执行。CSRF攻击(跨站请求伪造):攻击者诱导用户点击链接,使用用户的登录凭证发送恶意请求。防御措施:使用CSRF token,验证每个请求。点击劫持:攻击者将透明的恶意网站覆盖在真实网站上,诱导用户在不知情的情况下进行恶意操作。防御措施:使用X-FRAME-OPTIONS来防止网页被iframe调用。DoS攻击(拒绝服务攻击):恶意请求过多使得服务无法处理正常的请求。防御措施:限制访问频率、使用CDN(内容分发网络)等方式分散流量。SQL注入攻击:攻击者通过输入特殊的SQL查询语句,来获取数据库的敏感信息。防御措施:使用预处理语句(Prepared Statements)或参数化的SQL命令,拒绝直接执行动态生成的SQL语句。上传恶意文件:攻击者通过上传恶意文件,例如包含病毒或者后门的文件,来破坏服务器或者网页。防御措施:限制可上传文件类型,扫描上传的文件以防止上传恶意软件,对上传文件名严格过滤等。
阅读 34·2024年6月24日 16:43

为什么有移动端 1px 的问题以及有什么方案可以解决移动端 1px 的问题?

为什么存在 1px 问题移动端的1px问题主要是由于设备的物理像素和逻辑像素的不同所致。在高清显示屏(即设备独立像素比例devicePixelRatio大于1)的设备上,一个CSS像素可能会对应多个设备像素。这就导致了CSS的1px边框在高清屏上显示得比预期更粗。 1px以下是一些主要的解决1px问题的方案:视口缩放(Viewport Scale)视口缩放的原理是将页面的视口设置为设备宽度的一半或一部分,然后布局以这个新的视口宽度为基准进行。由于视口被缩小,一个CSS像素也就对应了更少的设备像素。 <meta name="viewport" content="width=device-width,initial-scale=.5,maximum-scale=.5,user-scalable=no">使用Media Query可以使用CSS的Media Query配合devicePixelRatio设定不同dpr下的边框样式,这样可以确保在不同dpr的设备上边框都看起来只有1px。 @media only screen and (-webkit-device-pixel-ratio: 2) { .border { border-width: 0.5px; } }使用伪元素 + transform: scaleY(.5)/scaleX(.5)利用伪元素,将元素的边框做一次.5的缩放,使得高清屏下1px边框变细。 .border:after { content: ''; position: absolute; bottom: 0; background: #000; width: 100%; height: 1px; transform: scaleY(.5); -webkit-transform: scaleY(.5); }使用SVG可以使用SVG矢量图形来实现1px边框。由于SVG是矢量图形,在任何分辨率的屏幕上都会很清晰。 <svg width="100%" height="1" xmlns="http://www.w3.org/2000/svg" version="1.1"> <line x1="0" y1="0" x2="100%" y2="0" stroke="black" stroke-width=".5"/> </svg>边框图片(Border Image)border-image 属性可以让你使用图像作为边框,你可以自由定义图像如何填充和拉伸。以上只是其中的一些常用解决方案,每种方法都有其适用范围和局限。在实际开发过程中,需要根据具体的应用情况选择最合适的方案。
阅读 131·2024年6月24日 16:43