JS 闭包题目思考
最近在网上看到这样的两道题目
代码片段一。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
代码片段二。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
1 var that = this;
2 return function(){ //zhi
3 return this.name;
4};
}
};
alert(object.getNameFunc()());
据说是出自红宝书. 看的觉得很又意思, 又仔细的研究了一下.写一下心路历程.
第一个还好,大多数都会答错第二道题目. 我仔细在debug了一下这个运行过程. 运行顺序是这样的
运行顺序
1. 调用getName() 这个function. 返回了一个匿名的function.但是需要注意的是.这个匿名的function 并没有运行. 而是在object.getNameFunc()() 第一个function运行完成之后再返回. 然后运行第一个function. 所以运行过程应该是这样的
2. object.getNameFunc() //运行getName里面的语句.但是这个函数只有一个 return function.所以只运行了一个return function();
3. function(){...}=object.getNameFunc().//运行了getNameFunc后返回了这个function()正常情况下,这个function不会运行. 但是注意题目,object.getNameFunc()() 这里有两个括号.也就是在getNameFunc()运行之后. 又紧接着运行了 匿名的function(){...}所以第三步应该是这样.
4. function(){...}(); 运行匿名函数. return this.name.
#### 所以整个运行过程是这样 getNameFunc(){};>>>function(){};>>>alert(str). 需要注意的是.
** 在运行getNameFunc() 的时候只会返回那个匿名函数.而不会运行内部的匿名函数.**
- 在搞清楚了运行过程的步骤,解决这两道题目就会特别简单.
第一道题
代码片段一。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
1. 运行getNameFunc() 得到 匿名function(){} ps: 仅仅是得到这个匿名函数,并不运行.
2. 运行function(){...} 得到了this.name. 因为这个函数是匿名函数,所以调用对象着是window.所以运行情况相当于是一个全局的函数.
而 alert(object.getNameFunc()()); 等价于下面的两步.
1. function(){}=getNameFunc() //第一步
2. alert(function(){return this.name}()); //第二步 运行这个匿名的函数
所以当运行匿名函数的时候,调动对象是window. 所以return this.name 就返回了一个全局的name
即 "The window"
第二道题
代码片段二。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
1 var that = this;
2 return function(){ //zhi
3 return that.name;
4};
}
};
alert(object.getNameFunc()());
-
第一步运行 getNameFun();
- 就是运行了两句话.
- var that =this //这个时候是obeject调用getNameFunc(),所以 that=object. 这个that 保存下来this 的直
- return function(); //只是return 没有运行.
- 就是运行了两句话.
-
第二步. 运行 getName()返回的匿名函数.即
function(){ return that.name }(); 返回了that.name="My object". 这个时候的this 其实是window对象.this.name="The window" 但是这个时候返回的是that.name.所以返回 "My obejct"
总结
- this 的直是不断在变化的. 所以如果想得到某个确定的直.就在他变化前保存下来.
- 匿名对象的调用者是window 对象.
- 闭包中返回的函数.当你不调用的时候是不运行的. 它仅仅是返回给你而已.