Javascript学习笔记:闭包题解(2)
代码:
1 var name='The Window'; 2 3 var object={ 4 name:'My Object', 5 getNameFunc:function(){ 6 return function(){ 7 return this.name; 8 }; 9 } 10 } 11 12 console.log(object.getNameFunc()());
问题:请写出该段代码的打印结果。
正确答案:'The Window'
解析:每个函数被调用时都会自动取得两个特殊的变量:this和arguments,内部函数在搜索这两个变量的时候,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。因此上面这段代码不存在闭包。所以this.name指向的不是object.name。那this指向的是什么呢?判断函数内部this的指向符合这几条原则:
第一、当函数作为单纯的函数调用时(即该函数不属于某一对象的方法),this指向全局对象,在浏览器中则指向window对象。在Node.js中则指向global对象。
第二、当函数作为某一对象的方法调用时,this指向该对象。
第三、作为构造函数调用时(用new调用),this指向新创建的对象。
第四、当通过call或者apply调用时,this指向call和apply第一个传进来的参数。如果参数为空,则this指向全局对象。
第五、除前四种以外的情况,则this指向全局对象。
由以上这五条判断可知,上面这段代码中的this指向的全局对象,所以this.name的值为'The Window'。如何才能让闭包返回'My Object'呢,可以通过下面这种方式:
1 var name='The Window'; 2 3 var object={ 4 name:'My Object', 5 getNameFunc:function(){ 6 var that=this; 7 8 return function(){ 9 return that.name; 10 }; 11 } 12 } 13 14 console.log(object.getNameFunc()());//My Object
即将包含闭包的函数的this用变量保存起来,然后再在闭包中使用。
arguments也存在和this同样的问题。如果想访问包含函数作用中的arguments或者this,那么必须将this或者arguments对象的引用保存到闭包能够访问到的变量中。