鍍金池/ 問(wèn)答/HTML/ js閉包this對(duì)象

js閉包this對(duì)象

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

在高級(jí)程序設(shè)計(jì)的第7章,7.2.2關(guān)于this對(duì)象中,有幾句話實(shí)在是不太明白:

以上代碼先創(chuàng)建了一個(gè)全局變量 name,又創(chuàng)建了一個(gè)包含 name 屬性的對(duì)象。這個(gè)對(duì)象還包含一個(gè)方法——getNameFunc(),它返回一個(gè)匿名函數(shù),而匿名函數(shù)又返回 this.name。由于 getNameFunc()返回一個(gè)函數(shù),因此調(diào)用 object.getNameFunc()()就會(huì)立即調(diào)用它返回的函數(shù),結(jié)果就是返回一個(gè)字符串。然而,這個(gè)例子返回的字符串是"The Window",即全局 name 變量的值。為什么匿名函數(shù)沒(méi)有取得其包含作用域(或外部作用域)的 this 對(duì)象呢?

前面曾經(jīng)提到過(guò),每個(gè)函數(shù)在被調(diào)用時(shí)都會(huì)自動(dòng)取得兩個(gè)特殊變量: this 和 arguments。內(nèi)部函數(shù)在搜索這兩個(gè)變量時(shí),只會(huì)搜索到其活動(dòng)對(duì)象為止,因此永遠(yuǎn)不可能直接訪問(wèn)外部函數(shù)中的這兩個(gè)變量。

1.只會(huì)搜索到其活動(dòng)對(duì)象??? 不是有個(gè)作用域鏈嗎?匿名活動(dòng)對(duì)象在最下面,在匿名對(duì)象中找不到,那就去上面的活動(dòng)對(duì)象去找咯?getNameFunc中找不到就去object去找咯。。。不就找到了嗎

2.因此永遠(yuǎn)不可能直接訪問(wèn)外部函數(shù)中的這兩個(gè)變量???是什么意思?外部函數(shù)是指哪個(gè)?

回答
編輯回答
乞許

他是在全局執(zhí)行的吧,所以他的this指向是window

2018年6月22日 11:06
編輯回答
故人嘆

你可以通過(guò)修改嘗試對(duì) this 加深一下理解 .

1) 將匿名函數(shù)獨(dú)立出來(lái)給個(gè)名字.

稍微調(diào)整如下:

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()); 

現(xiàn)在你再來(lái)看這個(gè) getThisName 這個(gè)原來(lái)你代碼里面的匿名函數(shù),你是不是可以很清楚的看出它的調(diào)用方是認(rèn)誰(shuí)了? 很顯示到最后調(diào)用這個(gè)方法時(shí)是隱式的全局變量 (window, 在瀏覽器環(huán)境)
它跟上面聲明的 object 沒(méi)有任何關(guān)系. 只是 object.getNameFunc 這個(gè)函數(shù)將這個(gè)函數(shù)作為返回值.
如果是返回的其他標(biāo)量,自然也不會(huì)發(fā)生關(guān)系.
另外你上面的書也提到了, thisarguments這兩個(gè)隱式的變量是在函數(shù)調(diào)用的時(shí)候才獲得的.
所以在這個(gè)函數(shù)被調(diào)用的時(shí)候明顯它的this 只能是全局的 this.

2) 將 object 直接跟 getThisName 建立關(guān)系:

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

觀察上面的輸出,你再加深以下對(duì)這句話的理解:

每個(gè)函數(shù)在被調(diào)用時(shí)都會(huì)自動(dòng)取得兩個(gè)特殊變量

3) 加深對(duì)函數(shù)調(diào)用的理解, 加上 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)); 

每個(gè)函數(shù)在被調(diào)用時(shí)都會(huì)自動(dòng)取得兩個(gè)特殊變量

同時(shí)你也可以通過(guò)使用 apply, call 等內(nèi)置函數(shù)原型的方法來(lái)指定函數(shù)調(diào)用時(shí)所使用的 this 對(duì)象. 如上所示.

JavaScript 的這一特點(diǎn), 跟 Java 等靜態(tài)語(yǔ)言是很不同的. Java 等靜態(tài)語(yǔ)言,往往由于你方法(注意這里沒(méi)有說(shuō)函數(shù))寫的地方就決定了 this 對(duì)象的指向,但是 JavaScript 是動(dòng)態(tài)語(yǔ)言這一點(diǎn)很不一樣. 所以還需要在后面的實(shí)踐中多多注意總結(jié)和理解.

2017年7月17日 08:02
編輯回答
雅痞

首先, 你對(duì)函數(shù)(function)沒(méi)有理解明白, 所以理解閉包的時(shí)候肯定會(huì)有困惑.
在函數(shù)內(nèi)部,有兩個(gè)特殊的對(duì)象arguments(參數(shù))和this。
this對(duì)象引用的是函數(shù)執(zhí)行環(huán)境的對(duì)象(當(dāng)在網(wǎng)頁(yè)全局作用域中調(diào)用函數(shù)時(shí),this對(duì)象引用的就是window, window是全局對(duì)象)

你可以理解匿名函數(shù)的執(zhí)行環(huán)境是全局. 所以它的this指向window.

不知道你明白沒(méi)有, 第一次回答問(wèn)題, 希望對(duì)你有幫助.

2017年2月16日 12:22
編輯回答
扯不斷

首先你的代碼是不是寫錯(cuò)了。object == getNameFunc ?

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

因?yàn)槭悄涿瘮?shù)

2017年8月18日 18:40