關鍵字 this
是指與
函式,表示其值會因
查看函式是以方法、獨立函式,或
「建構函式」。
呼叫函式時,它會在後方建立關鍵字 this
的例項。
也就是含有該函式的物件參照
可以在範圍內存取與其同時定義的屬性和方法。
使用 this
在某些方式上與宣告的變數大同小異
const
。與常數一樣,無法移除 this
,且其值不可
而是 this
關鍵字的物件方法和屬性
包含可修改
全域繫結
在函式或物件的結構定義外,this
會參照
globalThis
屬性,在大多數情況下是全域物件的參照
JavaScript 環境。若是在網路瀏覽器中執行的指令碼,
全域物件是 window
物件:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
在 Node.js 中,globalThis
是 global
物件:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
在嚴格模式外,this
也會指獨立項目中的全域物件
函式,因為父項 Window
是實際上「擁有」的物件
這些函式的作用
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
使用嚴格模式時,在獨立模式中,this
的值會是 undefined
函式:
(function() {
"use strict";
console.log( this );
}());
> undefined
進入嚴格模式前,this
的 null
或 undefined
值
會替換為全域物件的參照。有時候,系統可能會顯示
稱為「預設繫結」的全域繫結因為這種舊版行為
隱含繫結
當函式以物件方法的形式呼叫時,內部的 this
例項
方法是參照包含 方法的物件,讓該物件存取
與其相關的方法和屬性:
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
看起來 this
的值可能取決於函式及其函式方式
已定義封閉物件相反地,this
值的結構定義為
目前的「執行」結構定義。在此情況下,執行背景是指
myObject
物件會呼叫 myMethod
方法,因此 myObject
是值
(this
)就前文的情境來說,這似乎點出了技術性
範例不過,如要進一步使用 this
,這是一個重要的區別:
並以此收費
一般而言,在預期周圍程式碼不會出現 this
的情況下使用
任何特定結構這項規則的例外狀況是 ES5
箭頭函式。
箭頭函式中的 this
在「箭頭函式」中,
this
會解析為
廣泛包容環境:也就是說
箭頭函式中的 this
是指函式函式中的 this
值
最接近的背景資訊:
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
在上一個範例中,myObject.myMethod()
將 myObject
記錄為物件
「擁有」該方法,但 myObject.myArrowFunction()
會傳回 globalThis
(或 undefined
),因為箭頭函式中 this
的例項
就必須參照最高的封閉範圍
在以下範例中,myEnclosingMethod
會在
內含該值區的物件內部的 this
例項
箭頭函式現在參照該範圍內部的 this
值
(包含箭頭函式的方法)。由於
myEnclosingMethod
中的 this
值在您之後代表 myObject
定義箭頭函式,箭頭函式中的 this
也會參照
myObject
:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
明確繫結
隱含繫結可處理 this
的大部分用途。不過,
有時可能需要 this
值來代表「特定」執行作業
而不是假設使用情境說明如果略有過時
範例是在 setTimeout
回呼函式中使用 this
,
因為這個回呼的執行內容不重複:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
雖然 setTimeout
有這個缺點 緩解,現在
其他功能,類似「遺失」的問題「this
」已解決
方法是針對 this
的範圍內,建立明確參照
相關的背景資訊您有時可能會看見系統指派 this
的執行個體
使用舊版 that
、self
或 _this
等 ID
程式碼集以下是包含
傳送了 this
值。
使用 call()
、bind()
或 apply()
方法呼叫函式時,
this
明確參照要呼叫的物件:
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
明確繫結會覆寫隱含繫結提供的 this
值。
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
如果呼叫函式的方式可將 this
的值設為
undefined
或 null
,該值會由嚴格範圍以外的 globalThis
取代
模式:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
同樣地,如果呼叫函式的方式可將原始值提供給 this
值,則該值會取代
原始值的包裝函式物件
停用嚴格模式:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
在嚴格模式中,系統不會以任何方式強制將傳遞的 this
值強制轉換為物件,
即使是基本、null
或 undefined
值也是如此:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
new
個繫結
如果使用類別做為建構函式,
new
關鍵字,this
是指新建立的例項:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
同樣地,在使用 new
呼叫的建構函式函式中,this
的值
是指要建立的物件:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
事件處理常式繫結
在事件處理常式的結構定義中,this
的值會參照
呼叫該函式。在事件處理常式的回呼函式中,這表示 this
參照與處理常式相關聯的元素:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
當使用者與上一個程式碼片段中的 button
互動時,結果會是
包含 <button>
本身的元素物件:
> Button {}
如果箭頭函式用做事件監聽器回呼,
this
會再次由最接近的封閉執行環境提供。頂端
等級,這表示事件處理常式回呼函式中的 this
是
globalThis
(或嚴格模式中的 undefined
):
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
和其他物件一樣,使用 call()
、bind()
或 apply()
時
參照事件監聽器回呼函式的方法,this
請明確參照該物件:
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
隨堂測驗
對於在網路瀏覽器中執行的指令碼,什麼是全域物件
this
是指在函式之外或
物件結構定義?
undefined
物件window
物件browser
物件