在JavaScript裡,this是很多人剛開始學最困惑的地方,因為它不像其他語言固定指向物件
JS的this取決於函式被呼叫的方式,讓我們來看看吧
在不同情況下 this 會不一樣
console.log(this); // 在瀏覽器全域是 window
function test() {
console.log(this);
}
test(); // 也是 window(嚴格模式下是 undefined)
在物件方法裡:
const obj = {
name: 'Alice',
greet: function() {
console.log(this.name);
}
};
obj.greet(); // Alice
在物件方法裡呼叫,this
會指向該物件。
箭頭函式沒有自己的 this,它會沿用外層的 this:
const obj = {
name: 'Alice',
greet: () => {
console.log(this.name);
}
};
obj.greet(); // undefined(this 指向全域)
所以在物件方法裡通常不要用箭頭函式。
JS 提供三個方法來指定this
bind
會回傳一個新的函式,將this
永遠綁定成指定物件
範例:
function greet() {
console.log(`Hello, ${this.name}`);
}
const person = { name: 'Alice' };
const greetAlice = greet.bind(person);
greetAlice(); // Hello, Alice
call
會直接呼叫函式,同時指定this
,參數一個一個傳
範例:
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const person = { name: 'Bob' };
greet.call(person, 'Hi'); // Hi, Bob
apply
和call
很像,但參數要用陣列傳
範例:
greet.apply(person, ['Hello']); // Hello, Bob
小練習
1.寫一個函式 sayAge 印出 this.age,用 call 讓它印出不同物件的年齡。
2.用 bind 建立一個專門替某個人打招呼的函式。
function sayAge() {
console.log(this.age);
}
const person1 = { age: 20 };
const person2 = { age: 30 };
sayAge.call(person1); // 20
sayAge.call(person2); // 30
const greet = function() {
console.log(`Hello, ${this.name}`);
};
const alice = { name: 'Alice' };
const greetAlice = greet.bind(alice);
greetAlice(); // Hello, Alice
最後整理一下今天的內容就結束啦:this是由「呼叫方式」決定,不是由「宣告位置」決定,箭頭函式沒有自己的this
,會沿用外層,bind
會產生新函式固定this
,call
、apply
則是一次性呼叫函式指定this