共计 2467 个字符,预计需要花费 7 分钟才能阅读完成。
理解闭包形成的原因,理解定义时和运行时的区别。
面试题 1
var num = 1;
var o = {
num: 2,
add: function() {
this.num = 3;
console.log('add', this);
(function() {console.log('closure', this);
console.log(this.num);
this.num = 4;
})();
console.log(this.num);
},
sub: function() {console.log(this.num);
}
}
o.add();
console.log(o.num);
console.log(num);
var sub = o.sub;
sub();
// 请写出输出结果
zyx456 的解释:
01,o.add();
第一个 console.log(‘add’, this);// 输出 o 这个对象。
在对象方法中,方法中的 this 指向这个对象。
第一个 this.num = 3;
表示:o.num =3;
02,匿名自执行函数中的 this,指向全局环境变量。为 window。
所以
(function() { console.log('closure', this);// 这里的 this 是指向哪里?window
console.log(this.num);//1
this.num = 4;//window.num = 4;
})();
匿名自执行函数的 this.num 为 window.num。为 1。
this.num = 4;//window.num = 4;
03,
console.log(o.num);//3,因为前面修改了 o.num=3;
04,console.log(num);//4
这里,num 为 window.num。
05,var sub = o.sub;
sub();//4
zyx456:sub 为函数。全局函数中的 this 指向全局环境,也就是 window。
所以为 window.num 为 4;
面试题 2
function fun(n,o) {console.log(o)
return {fun:function(m){return fun(m,n);
}
};
}
var a = fun(0);
a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
// 问: 三行 a,b,c 的输出分别是什么?
zyx456 分析:
var a =fun(0);
首先输出 console.log(o);// o 未定义,为 undefined;
a = {fun:function(m){return fun(m,0);
}
}
a.fun(1);// 返回 fun(1,0);=> console.log(0)=>0
a.fun(2);// 返回 fun(2,0);=>console.log(0)=>0
a.fun(3)// 返回 fun(3,0);=>console.log(0)=>0
所以:第一行输出 undefined,0,0,0
然后看第二行:var b = fun(0).fun(1).fun(2).fun(3);
fun(0)
首先输出 console.log(o);// o 未定义,为 undefined;
等效于
{fun:function(m){return fun(m,0);
}
}
fun(0).fun(1)
return fun(1,0)
fun(1,0) 先输出 =>console.log(0)=>0
最后 return 结果为
{fun:function(m){return fun(m,1);
}
}
fun(0).fun(1).fun(2)
等同于
return fun(2,1)
fun(2,1)-> 输出 console.log(1);=>1
最后 return 结果为
{fun:function(m){return fun(m,2);
}
}
fun(0).fun(1).fun(2).fun(3)
等同于
return fun(3,2)
fun(2,1)-> 输出 console.log(2);=>2
最后 return 结果为
{fun:function(m){ return fun(m,2);
}
}
所以:第一行输出 undefined,0,1,2
最后看第三行:var c = fun(0).fun(1); c.fun(2); c.fun(3);
var c=fun(0).fun(1);
同第二行的 b。会输出 undefined 和 0,
c 为
{fun:function(m){return fun(m,1);
}
}
c.fun(2)
return fun(2,1)=> 输出 1。可以看第二行 b。
c.fun(3)
return fun(3,1)=> 输出 1。可以看第二行 b。
所以:第一行输出 undefined,0,1,1
面试题 3
// 最基础题
for(var i = 1; i < 10; i ++){setTimeout(function(){console.log(i);
}, 1000);
}
// 变体一
for (var i = 1; i < 10; i++) {(function(i){setTimeout(function(){console.log(i);
}, i * 1000);
})(i);
}
// 变体二
for (var i = 1; i < 10; i++) {(function(){setTimeout(function(){console.log(i);
}, i * 1000);
})();}
// 变体三
for (var i = 1; i < 10; i++) {(function(){setTimeout(function(i){console.log(i);
}, i * 1000);
})();}
zyx456:
最基础:
1s 后运行定时器,此时 for 循环已结束,i 为 10。
变体 1:
依次 1 秒输出一个数字,闭包会使用 for 循环的值。
依次输出 1~9
变体 2:
依次每隔 1 秒输出 10,10,10.。。。。
变体 3:
在匿名自执行函数中,i 未定义。所以输出 9 个 undefined。