js闭包this对象

var name = "The Window";
var getNameFunc= {
    name: "My Object",
    getNameFunc: function() {
        return function() {
            return this.name;
        };
    }
};
alert(object.getNameFunc()()); //"The Window"(在非严格模式下)

在高级程序设计的第7章,7.2.2关于this对象中,有几句话实在是不太明白:

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

前面曾经提到过,每个函数在被调用时都会自动取得两个特殊变量: this 和 arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。

1.只会搜索到其活动对象??? 不是有个作用域链吗?匿名活动对象在最下面,在匿名对象中找不到,那就去上面的活动对象去找咯?getNameFunc中找不到就去object去找咯。。。不就找到了吗

2.因此永远不可能直接访问外部函数中的这两个变量???是什么意思?外部函数是指哪个?

阅读 4.6k
4 个回答

你可以通过修改尝试对 this 加深一下理解 .

1) 将匿名函数独立出来给个名字.

稍微调整如下:

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

现在你再来看这个 getThisName 这个原来你代码里面的匿名函数,你是不是可以很清楚的看出它的调用方是认谁了? 很显示到最后调用这个方法时是隐式的全局变量 (window, 在浏览器环境)
它跟上面声明的 object 没有任何关系. 只是 object.getNameFunc 这个函数将这个函数作为返回值.
如果是返回的其他标量,自然也不会发生关系.
另外你上面的书也提到了, thisarguments这两个隐式的变量是在函数调用的时候才获得的.
所以在这个函数被调用的时候明显它的this 只能是全局的 this.

2) 将 object 直接跟 getThisName 建立关系:

var name = "The Window";
function getThisName(){
    return this.name
}
var object = {
    name: "My Object",
    getNameFunc:getThisName 
};
console.log(object.getNameFunc()); // 输出: My Object
var getThisNameFunc = object.getNameFunc; 
console.log(getThisNameFunc()); // 输出: The Window

观察上面的输出,你再加深以下对这句话的理解:

每个函数在被调用时都会自动取得两个特殊变量

3) 加深对函数调用的理解, 加上 applycall
你看一下如下代码的输出:

var name = "The Window";
function getThisName(){
    return this.name
}
var object = {
    name: "My Object",
    getNameFunc:getThisName 
};
console.log(object.getNameFunc()); 
var getThisNameFunc = object.getNameFunc
console.log(getThisNameFunc()); 
console.log(getThisNameFunc.apply(object)); 
console.log(getThisNameFunc.call(object)); 

每个函数在被调用时都会自动取得两个特殊变量

同时你也可以通过使用 apply, call 等内置函数原型的方法来指定函数调用时所使用的 this 对象. 如上所示.

JavaScript 的这一特点, 跟 Java 等静态语言是很不同的. Java 等静态语言,往往由于你方法(注意这里没有说函数)写的地方就决定了 this 对象的指向,但是 JavaScript 是动态语言这一点很不一样. 所以还需要在后面的实践中多多注意总结和理解.

新手上路,请多包涵

首先, 你对函数(function)没有理解明白, 所以理解闭包的时候肯定会有困惑.
在函数内部,有两个特殊的对象arguments(参数)和this。
this对象引用的是函数执行环境的对象(当在网页全局作用域中调用函数时,this对象引用的就是window, window是全局对象)

你可以理解匿名函数的执行环境是全局. 所以它的this指向window.

不知道你明白没有, 第一次回答问题, 希望对你有帮助.

首先你的代码是不是写错了。object == getNameFunc ?

完整作用域链 匿名()->window

因为是匿名函数

新手上路,请多包涵

他是在全局执行的吧,所以他的this指向是window

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题