理解閉包造成的緣由,理解定義時和運行時的區別。面試
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。