與其他語言相比弱贼,函數(shù)的
this
關(guān)鍵字在 JavaScript 中的表現(xiàn)略有不同,此外磷蛹,在嚴(yán)格模式和非嚴(yán)格模式之間也會有一些差別吮旅。在絕大多數(shù)情況下,函數(shù)的調(diào)用方式?jīng)Q定了
this
的值味咳。this
不能在執(zhí)行期間被賦值沉馆,并且在每次函數(shù)被調(diào)用時this
的值也可能會不同嘉抒。ES5引入了bind方法來設(shè)置函數(shù)的this
值,而不用考慮函數(shù)如何被調(diào)用的,ES2015 引入了支持this
詞法解析的箭頭函數(shù)(它在閉合的執(zhí)行上下文內(nèi)設(shè)置this
的值)箕慧。
作為 JavaScript 中一個最撲朔迷離的關(guān)鍵字,this
也成為面試中最受考官歡迎并使用的一個考點预明∽粗看了一些文章后贸铜,你可能越看越迷糊,這很正常聂受。不過今天我以 MDN 的文檔庫為基礎(chǔ)蒿秦,把一些學(xué)習(xí)心得記錄一下。
定義
this
是函數(shù)作用域中自動生成的特殊的標(biāo)識符關(guān)鍵字蛋济,可以將它當(dāng)作一個指針來理解棍鳖。
不同環(huán)境下的 this 指向
按照 ECMAScript 規(guī)范我們討論兩種常用可執(zhí)行代碼(上下文環(huán)境):
- 全局代碼(Global code)
- 函數(shù)代碼(Function code)
1、全局上下文
無論是否在嚴(yán)格模式下碗旅,在全局執(zhí)行上下文中(在任何函數(shù)體外部)this
都指代全局對象渡处。
// 在瀏覽器中, window 對象同時也是全局對象:
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "MDN";
console.log(window.b) // "MDN"
console.log(b) // "MDN"
2、函數(shù)上下文
在函數(shù)內(nèi)部祟辟,this
的值取決于函數(shù)被調(diào)用的方式医瘫。以下我們簡單討論三種。
2.1 簡單調(diào)用
因為下面的代碼不是在嚴(yán)格模式下執(zhí)行旧困,且 this
的值不是通過調(diào)用設(shè)置的醇份,所以 this
的值默認(rèn)指向全局對象。
function f1(){
return this;
}
// 在瀏覽器中:
f1() === window; // 在瀏覽器中吼具,全局對象是window
// 在Node中:
f1() === global;
然而僚纷,在嚴(yán)格模式下,this
將保持他進(jìn)入執(zhí)行上下文時的值拗盒,所以下面的this將會默認(rèn)為 undefined
怖竭。
function f2(){
"use strict"; // 這里是嚴(yán)格模式
return this;
}
f2() === undefined; // true
所以,在嚴(yán)格模式下陡蝇,如果 this
未在執(zhí)行的上下文中定義痊臭,那它將會默認(rèn)為 undefined
。
2.2 作為對象的方法
當(dāng)以對象里的方法的方式調(diào)用函數(shù)時毅整,它們的 this
是調(diào)用該函數(shù)的對象趣兄。
var o = {
prop: 37,
f: function() {
return this.prop;
}
};
console.log(o.f()); // logs 37
我們也可以首先定義函數(shù),然后再將其附屬到 o.f
悼嫉。這樣做會導(dǎo)致相同的行為艇潭,也就是說,這樣的行為不受函數(shù)定義方式或位置的影響戏蔑。
var o = { prop: 37 };
function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // logs 37
類似的蹋凝,this
的綁定只受最靠近的成員引用的影響。
o.b = { g: independent, prop: 42 };
console.log(o.b.g()); // 42
2.3 作為構(gòu)造函數(shù)
當(dāng)一個函數(shù)用作構(gòu)造函數(shù)時(使用 new 關(guān)鍵字)总棵,它的 this
被綁定到正在構(gòu)造的新對象鳍寂。
簡單總結(jié)
最后,引用知乎的幾個簡單論斷:
-
this
永遠(yuǎn)指向函數(shù)運行時所在(最近)的對象情龄,而不是函數(shù)被創(chuàng)建時所在的對象迄汛; - 如果是
call
捍壤、apply
、with
鞍爱,指定的this
是誰鹃觉,就是誰; - 普通的函數(shù)調(diào)用睹逃,函數(shù)被誰調(diào)用盗扇,
this
就是誰。
參考
1沉填、根治JavaScript中的this-ECMAScript規(guī)范解讀
2疗隶、你不懂JS: this 與對象原型 - this 是什么?
3翼闹、你不懂JS: this 與對象原型 - 第二章: this 豁然開朗斑鼻!
4、JS 中 this 關(guān)鍵字詳解
5橄碾、徹底理解js中this的指向卵沉,不必硬背
6、用自然語言的角度理解JavaScript中的this關(guān)鍵字