JavaScript闭包--this对象

this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this对象指向window,而当函数作为某个对象X的方法调用的时候,this对象指向X对象。不过,匿名函数的执行环境具有全局性,因此其this对象通常指向window。但是由于编写闭包的方式不同,这一点可能不会那么明显。我们看下面一个例子:

var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        return function(){
            return this.name;
        };
    }
};

console.log(object.getNameFunc()()); //"The Window"(非严格模式)

这段代码创建了一个全局变量name,有创建了一个含有name属性的对象。这个对象还包含了一个方法:getNameFunc(),它返回一个匿名函数,匿名函数返回this.name。由于getNameFunc返回一个函数,因此调用object.getNameFunc()()就会立即调用它返回的函数,结果就是返回一个字符串。然而,这个例子返回的字符串是“The Window”, 是全局变量的值,为什么匿名函数没有取得其包含作用域(或外部作用域)的this对象呢?

JavaScript的非严格模式下面,如果函数的作用域不明确的话,那么this对象统统是指向window的。

每个函数在被调用时都会自动获取两个特殊变量:this和arguments。内部函数闭包在搜索这两个变量的时候,只会搜索到该闭包的活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。
JavaScript闭包--this对象_第1张图片
从之前的例子里面可以看出,闭包使用的this和arguments都是闭包的活动对象自己的,而不能使用其外部函数的活动变量的,而其他的属性里面propertyName是可以通过作用域链获取到的。

那么,怎么让闭包访问外部环境的this对象呢?

var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        var that = this;
        return function(){
            return that.name;
        };
    }
};

console.log(object.getNameFunc()()); //"The Object"

上述代码片段与之前代码片段的不同之处在于,在定义匿名函数之前,我们把this指针对象赋值给了另一个变量that,在定义闭包之后,闭包是可以访问这个that变量,因为它是我们在外部函数中特意声明的一个变量。即使在外部函数返回之后,that也仍然引用着object,所以调用object.getNameFunc()()就返回”My Object”。

因为this和arguments都存在一样的问题,所以如果想访问外部函数作用域中的arguments对象,也必须将该对象的引用保存到另一个闭包能访问的变量中。

你可能感兴趣的:(JavaScript)