内容主要来源于网络文章4byte
- 文章主旨是为了进一步理解闭包如果运作,最好是先自己动脑想一下答案再看解题思路
- 直接抛题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22function func(closure, more){
log(more);
return {
func: function(innerClosure){
return func(innerClosure, closure);
}
};
}
function log(s){
var _d = document.createElement('div');
_d.innerHTML = s;
document.body.appendChild(_d);
}
var temp = func(0);
temp.func(1);
temp.func(2);
temp.func(3);
var temp2 = func(0).func(1).func(2).func(3);
var temp3 = func(0).func(1);
temp3.func(2);
temp3.func(3);
//Question: 以上函数执行后出现在body上的结果是什么?
基础知识
- 先了解声明函数的方式
function fn1(){}
var fn1=function (){}
var fn1=function xxcanghai(){};
new Function("alert(987654321)")
(function(){alert(1);})();(function fn1(){alert(1);})();
- 要点:理解作用域
1
2
3
4
5
6
7
8
9
10
11var o={
fn:function (){
console.log(fn);
}
};
o.fn();//ERROR报错
/*提升*/
var fn=function (){
console.log(fn);
};
fn();//function (){console.log(fn);};正确
解析思路
解析temp
可以得知,第一个func(0)是在调用第一层func函数。第二个func(1)是在调用前一个func的返回值的func函数
后面几个func(1),func(2),func(3),函数都是在调用第二层func函数。
在第一次调用func(0)时,more为undefined;
第二次调用func(1)时innerClosure为1,此时func闭包了外层函数的closure,也就是第一次调用的closure=0,即innerClosure=1,closure=0,并在内部调用第一层func函数func(1,0);所以more为0;
第三次调用func(2)时innerClosure为2,但依然是调用temp.func,所以还是闭包了第一次调用时的时innerClosure为1,此时func闭包了外层函数的closure,也就是第一次调用的closure,所以内部调用第一层的func(2,0);所以more为0
第四次同理;
最终答案为undefined,0,0,0
解析temp2
先从func(0)开始看,肯定是调用的第一层func函数;而他的返回值是一个对象,所以第二个func(1)调用的是第二层func函数,后面几个也是调用的第二层func函数。
在第一次调用func(0)时,more为undefined;
第二次调用func(1)时innerClosure为1,此时func闭包了外层函数的closure,也就是第一次调用的closure=0,即innerClosure=1,closure=0,并在内部调用第一层func函数func(1,0);所以more为0;
第三次调用 .func(2)时innerClosure为2,此时当前的func函数不是第一次执行的返回对象,而是第二次执行的返回对象。而在第二次执行第一层func函数时(1,0)所以closure=1,more=0,返回时闭包了第二次的closure,遂在第三次调用第三层func函数时innerClosure=2,closure=1,即调用第一层func函数func(2,1),所以more为1;
第四次调用 .fun(3)时innerClosure为3,闭包了第三次调用的closure,同理,最终调用第一层func函数为func(3,2);所以more为2;
最终答案为undefined,0,1,2
解析temp3
- func(0)为执行第一层func函数,.func(1)执行的是func(0)返回的第二层func函数,这里语句结束,temp3存放的是func(1)的返回值,而不是func(0)的返回值,所以temp3中闭包的也是func(1)第二次执行的closure的值。temp3.func(2)执行的是func(1)返回的第二层func函数,temp3.func(3)执行的也是func(1)返回的第二层func函数。
- 在第一次调用第一层func(0)时,more为undefined;
- 第二次调用 .func(1)时innerClosure为1,此时func闭包了外层函数的closure,也就是第一次调用的closure=0,即innerClosure=1,closure=0,并在内部调用第一层func函数func(1,0);所以more为0;
- 第三次调用 .func(2)时innerClosure为2,此时func闭包的是第二次调用的closure=1,即innerClosure=2,closure=1,并在内部调用第一层fun函数func(2,1);所以more为1;
- 第四次.func(3)时同理,但依然是调用的第二次的返回值,最终调用第一层func函数func(3,1),所以more还为1
- 最终答案:undefined,0,1,1
不混淆版
转成这样会好理解些
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function someFunc(closure, more){
log(more);
return {
innerFunc: function(innerClosure){
return someFunc(innerClosure, closure);
}
};
}
function log(s){
var _d = document.createElement('div');
_d.innerHTML = s;
document.body.appendChild(_d);
}
var temp = someFunc(0);
temp.innerFunc(1);
temp.innerFunc(2);
temp.innerFunc(3);
var temp2 = someFunc(0).innerFunc(1).innerFunc(2).innerFunc(3);
var temp3 = someFunc(0).innerFunc(1);
temp3.innerFunc(2);
temp3.innerFunc(3);