Skip to content

this關鍵字

在 JavaScript 中, this 是一個非常強大的關鍵字,用於引用當前執行上下文(context)中的物件。this 的值會根據它被使用的環境不同而改變,因此理解 this 的作用和運作機制對於編寫有效的 JavaScript 代碼至關重要。

以下是對 this 關鍵字的詳細說明,涵蓋了它在不同情境下的行為和使用方式。

1. 全域上下文(Global Context)

在全域範圍中,this 通常指向全域物件。在瀏覽器環境中,這個全域物件是 window

console.log(this);  // 在瀏覽器中,輸出 window 物件

如果是在 Node.js 環境中,this 會指向 global 物件,但在模組化的 JavaScript 中,它通常指向當前模組的 exports 物件。

2. 函式內的 this

在普通函式中,this 的值取決於函式的調用方式。

2.1 嚴格模式下的 this

在非嚴格模式下(non-strict mode),當函式作為普通函式調用時,this 會指向全域物件(瀏覽器中的 window 或 Node.js 中的 global)。然而,在嚴格模式(strict mode)下,this 將是 undefined

function showThis() {
    "use strict";
    console.log(this);  // 嚴格模式下輸出 undefined,非嚴格模式下輸出 window(或 global)
}

showThis();

2.2 方法中的 this

當函式作為物件的方法被調用時,this 會指向該物件。

const person = {
    name: 'Alice',
    greet: function() {
        console.log(this.name);  // this 指向 person 物件,輸出 "Alice"
    }
};

person.greet();

3. 箭頭函式中的 this

箭頭函式(Arrow Functions)中的 this 行為與普通函式不同。箭頭函式不會建立自己的 this,它會繼承來自外層函式或全域上下文的 this 值。

const person = {
    name: 'Alice',
    greet: function() {
        const innerArrowFunction = () => {
            console.log(this.name);  // this 繼承自外層的 greet 函式,指向 person 物件
        };
        innerArrowFunction();
    }
};

person.greet();  // 輸出 "Alice"

4. 建構函式中的 this

當使用 new 關鍵字調用建構函式時,this 指向新創建的物件。

function Person(name) {
    this.name = name;
}

const person1 = new Person('Bob');
console.log(person1.name);  // this 指向 person1,輸出 "Bob"

5. callapplybind 方法

你可以使用 callapplybind 方法來顯式地設定 this 的值。

  • call:用於調用函式並顯式設定 this 值。參數用逗號分隔傳遞。

    function greet() {
        console.log(this.name);
    }
    
    const person = { name: 'Charlie' };
    greet.call(person);  // this 被設定為 person,輸出 "Charlie"
    

  • apply:與 call 類似,但參數以陣列的形式傳遞。

    function greet(greeting) {
        console.log(greeting + ', ' + this.name);
    }
    
    const person = { name: 'Charlie' };
    greet.apply(person, ['Hello']);  // this 被設定為 person,輸出 "Hello, Charlie"
    

  • bind:返回一個新函式,且 this 被永久綁定到指定的物件上。

    function greet() {
        console.log(this.name);
    }
    
    const person = { name: 'Charlie' };
    const boundGreet = greet.bind(person);
    boundGreet();  // this 被設定為 person,輸出 "Charlie"
    

6. DOM 事件處理中的 this

在 DOM 事件處理器中,this 指向觸發事件的 DOM 元素。

document.getElementById('myButton').addEventListener('click', function() {
    console.log(this.id);  // this 指向被點擊的按鈕,輸出按鈕的 id
});

在使用箭頭函式作為事件處理器時,由於箭頭函式不綁定自己的 thisthis 會指向事件處理器外層的上下文,而不是 DOM 元素。

document.getElementById('myButton').addEventListener('click', () => {
    console.log(this.id);  // 這裡的 this 取決於外層作用域的上下文,可能是 undefined
});

7. this 在類別中的使用

在 ES6 類別中,this 指向類別的實例。

class Person {
    constructor(name) {
        this.name = name;
    }

    greet() {
        console.log(`Hello, ${this.name}`);
    }
}

const person = new Person('David');
person.greet();  // this 指向 person 實例,輸出 "Hello, David"
在類別方法中,this 會指向該方法所屬的實例。

總結

this 是 JavaScript 中強大且靈活的關鍵字,其值根據上下文環境而變化。理解 this 的運作機制,對於編寫和調試 JavaScript 代碼非常重要。根據 this 所在的上下文不同,它可以指向全域物件、當前的物件實例、甚至是 DOM 元素等,因此學會如何控制和利用 this 將幫助你更好地掌握 JavaScript。