理解闭包造成的缘由,理解定义时和运行时的区别。面试
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指向这个对象。spa
第一个this.num = 3;code
表示:o.num =3;对象
02,匿名自执行函数中的this,指向全局环境变量。为window。blog
因此rem
(function() { console.log('closure', this);//这里的this是指向哪里?window console.log(this.num);//1 this.num = 4;//window.num = 4; })();
匿名自执行函数的this.num为window.num。为1。it
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;
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
// 最基础题 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。