此關鍵字

關鍵字 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 中,globalThisglobal 物件:

$ 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

進入嚴格模式前,thisnullundefined 值 會替換為全域物件的參照。有時候,系統可能會顯示 稱為「預設繫結」的全域繫結因為這種舊版行為

隱含繫結

當函式以物件方法的形式呼叫時,內部的 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 的執行個體 使用舊版 thatself_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 的值設為 undefinednull,該值會由嚴格範圍以外的 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 值強制轉換為物件, 即使是基本、nullundefined 值也是如此:

"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 會再次由最接近的封閉執行環境提供。頂端 等級,這表示事件處理常式回呼函式中的 thisglobalThis (或嚴格模式中的 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 物件