01 前言
随着市场的改变,前端面试形式和内容都发生了巨大的变化。以前面试前端,只要背一背八股文,就能应付过去。而最近有较多的同学去面试,基本都会遇到笔试题,跟面试官沟通交流的时候都是问一些场景题、逻辑题,几乎很少遇到以前背八股文那套了。
那我也给大家总结总结最近高频出现简单又容易踩坑的面试笔试题吧!
02 以下代码打印结果?
- 主要考察var定义变量特性和异步代码
for (var i = 0; i<5; i++) {
setTimeout(() => {
console.log(i)
}, 0)
}
结果: 一共输出5次,每次值都为5。
原因:
1. 因为在循环中使用了setTimeout 函数创建了五个异步任务,并将它们放入事件队列中等待执行。
2. 当这些任务被执行时,它们都会访问同一个变量 i,由于var 在此声明的变量属于全局变量,这5个异步代码共享了同一个变量 i。
3. 当循环结束后,变量 i 的值为 5,因此当这些异步任务被执行时,它们都会访问并输出变量 i 的最终值,即 5。
- 考察let定义变量存在块级作用域
for(let i = 0;i<5;i++){
setTimeout(()=>{
console.log(i)
},0)
}
结果: 一共输出5次,值分别为0、1、2、3、4。
原因:
1. 因为在循环中使用了let关键字声明变量 i,这将会创建一个块级作用域。
2. 每次循环迭代时,都会创建一个新的变量 i,并将其绑定到对应的循环迭代中。
3. 当setTimeout函数被执行时,它们都能够访问自己所在迭代中的变量 i。因此,第一个异步任务中的 i 值为 0,第二个异步任务中的 i 值为 1,以此类推。每个异步任务都只能访问其所在迭代中的变量 i,因此依次输出的结果是 0、1、2、3、4。
以上两个代码块就定义变量的关键字不一样,导致结果完全不一样,虽然改变的点很小,但却很容易以被面试者忽略,最近就有不少的同学踩到此坑!
- 考察变量提升(预解析)
console.log(x);
var x = 1;
function x() {}
结果: 输出fucntion x(){}
原因:
在js代码执行之前会先对代码进行预解析,也就是所谓的变量提升。
其中会预解析两部分,一是var定义的变量,只提升变量,而不提升值;二是声明式定义的函数,会把整函数提升。
那么根据以上描述,此时预解析的过程是这样的:
1. 先提升var定义的x变量,在代码最顶部就存在一句var x ,此时x的值为undefined;
2. 然后提升声明式函数,因为函数名和x一样,所以相当于把这个这个函数赋值给x变量。
预解析结束才会执行执行console.log(x) 就打印fucntion x(){}函数。
虽然只有3句代码,不要忽略,往往就是越简单越容易掉坑的!
- 考察this指向
var name = "window";
var person = {
name: "person",
sayName: function () {
console.log(this.name);
},
};
function sayName() {
var sss = person.sayName;
sss();
person.sayName(); //结果2是'person'
(b = person.sayName)(); //3.结果是'window'
}
sayName();
结果:window、person、window。
原因:
1. 第一次输出window,因为在该函数中,this 指向全局对象 window。变量sss中保存的是对函数person.sayName的引用,sss()调用是作为普通函数调用时,所以this会指向全局对象。
2. 第二次输出 person,因为在该函数中,this指向对象person。通过使用对象方法的方式调用sayName函数,那么函数中this指向调用该函数的对象,即函数中this指向person。
3. 第三次输出 window,因为在该函数中,this指向对象window。由于将person.sayName赋值给了变量b,然后执行函数的自调用,自调用是将b作为普通函数进行调用,因此函数中this指向window。
总的来说,JavaScript 函数的中this关键字取决于函数的调用方式,把函数的调用方式理解清楚,这些代码执行结果就so easy啦~
03 结语
这篇文章就先写这些啦,希望对正在面试或者即将要面试的朋友有帮助,期待更多类似的面试吗?可以留言给出你的想法和建议哦!
让学习变得有趣
让编程不再困难