1访敌、
var result = [];
var a = 3;
var total = 0;
function foo(a) {
var i = 0;
for (; i < 3; i++) {
result[i] = function() {
total += i * a;
console.log(total);
}
}
}
foo(1);
result[0]();
result[1]();
result[2]();
這道題中凉敲,局部變量var a = 3
是個(gè)干擾因素,因?yàn)椴⒉粫?huì)訪問到它寺旺。
這道題的關(guān)鍵是
result[i] = function() {
total += i * a;
console.log(total);
}
這里面的i和a是閉包
不妨從頭講一下這道題的執(zhí)行過程
因?yàn)楹瘮?shù)的聲明是不會(huì)執(zhí)行的爷抓,所以直接看函數(shù)的執(zhí)行部分foo(1)
首先看返回值,它沒有顯式地聲明返回值阻塑,所以是undefined废赞。
其次看它的屬性,它有個(gè)用var聲明的屬性i叮姑,初始值為0。
然后它通過一個(gè)for循環(huán)据悔,可以理解為往外部數(shù)組res里面push匿名函數(shù)传透。
所以當(dāng)執(zhí)行foo(1)
之后
res里面一共push了三個(gè)函數(shù),每個(gè)函數(shù)都是一樣的极颓,函數(shù)如下:
function() {
total += i * a;
console.log(total);
}
這時(shí)候搞懂total朱盐,i,a這三個(gè)變量的值菠隆,也就解決了這道題兵琳。
total:外部變量狂秘,初始值為0,很好理解躯肌,沒有坑者春。
a:foo(a)函數(shù)的參數(shù) ,有一是通過foo(1)對(duì)res進(jìn)行賦值的清女,所以a=1钱烟。
i : 由于i是用var聲明的,所以它在for循環(huán)里面嫡丙,都是一個(gè)i拴袭。這句話聽起來是有點(diǎn)拗口,意思就是當(dāng)聲明函數(shù)的時(shí)候曙博,引用了這個(gè)i拥刻,它不會(huì)把當(dāng)前的值直接傳進(jìn)去,而是把i的地址傳進(jìn)去父泳,當(dāng)函數(shù)被調(diào)用的時(shí)候般哼,才會(huì)查詢i的值,所以當(dāng)foo(1)執(zhí)行完的時(shí)候尘吗,i=3逝她。
所以最后會(huì)打印出 3 6 9。
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);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);c.fun(2);c.fun(3);
這道題首先要明白黔宛,fun()返回的是一個(gè)對(duì)象,對(duì)象里面有一個(gè)fun屬性擒贸,對(duì)應(yīng)的是一個(gè)函數(shù)臀晃,該函數(shù)的返回值為fun();
- 1 先看看第一行
var a = fun(0);a.fun(1);a.fun(2);a.fun(3);
先看var a = fun(0)
它會(huì)打印出什么介劫,而且它是什么
執(zhí)行fun(0),由于只傳了一個(gè)參數(shù)徽惋,所以console.log(n)
會(huì)打印出undefined。
他會(huì)return一個(gè)對(duì)象:
{fun : function(m){
return fun(m,0)
}
所以a.fun(1)
就是執(zhí)行
function(1){
return fun(1,0)
}
那么就會(huì)打印出0座韵;
a.fun(2)险绘、a.fun(3)
與a.fun(1)
類似,所以最后這一行會(huì)打印出
undefined 0 0 0
1.2 看第二行
var b = fun(0).fun(1).fun(2).fun(3);
首先 fun(0)
會(huì)執(zhí)行console.log(o)誉碴,打印出undefined宦棺,這時(shí)候的返回值為:
{fun : function(m){
return fun(m,0)
}
}
這時(shí)候執(zhí)行fun(0).fun(1)
也就是執(zhí)行fun(1,0)
這時(shí)候會(huì)console.log(o),打印出0然后返回值為:
{fun : function(m){
return fun(m,1)
}
}
然后執(zhí)行var b = fun(0).fun(1).fun(2)
也就是執(zhí)行fun(2,1)
這時(shí)候會(huì)console.log(o)黔帕,打印出1然后返回值為:
{fun : function(m){
return fun(m,2)
}
}
最后執(zhí)行var b = fun(0).fun(1).fun(2).fun(3)
和前面同理代咸,所以最后打印出的是:undefined 0 1 2
1.3 看第三行
var c = fun(0).fun(1);c.fun(2);c.fun(3);
不妨分為 var c = fun(0).fun(1);
和c.fun(2);c.fun(3);
兩個(gè)部分
先看第一部分var c = fun(0).fun(1);
首先執(zhí)行fun(0),打印出undefined然后返回一個(gè)對(duì)象:
{fun : function(m){
return fun(m,0)
}
所以var c = fun(0).fun(1);就是執(zhí)行fun(1,0)會(huì)打印出0,然后返回
{fun : function(m){
return fun(m,1)
}
所以c.fun(2);c.fun(3);
就是fun(2,1),fun(3,1)成黄,都會(huì)打印出1
所以最后的結(jié)果是undefined 0 1 1呐芥;