JavaScript中的 this 是一個(gè)非常重要的概念,它指向當(dāng)前執(zhí)行上下文的對(duì)象。由于JavaScript是一門(mén)動(dòng)態(tài)語(yǔ)言,this 的指向在運(yùn)行時(shí)才能確定,可能會(huì)因?yàn)檎{(diào)用方式和執(zhí)行環(huán)境的不同而有所變化。
this 的指向可以通過(guò)四種調(diào)用方式來(lái)決定:
- 作為函數(shù)調(diào)用時(shí),
this指向全局對(duì)象(瀏覽器中為window對(duì)象,Node.js中為global對(duì)象)。 - 作為方法調(diào)用時(shí),
this指向調(diào)用該方法的對(duì)象。 - 使用
call()或apply()方法調(diào)用時(shí),this指向第一個(gè)參數(shù)傳入的對(duì)象。 - 使用
new關(guān)鍵字調(diào)用構(gòu)造函數(shù)時(shí),this指向新創(chuàng)建的對(duì)象。
除了上述四種方式,還有一些特殊情況需要注意,例如箭頭函數(shù)中的 this 指向是定義函數(shù)時(shí)的上下文,不會(huì)隨著調(diào)用環(huán)境的改變而改變。
總之,JavaScript中的this是一個(gè)非常靈活和有用的概念,可以根據(jù)不同的調(diào)用方式來(lái)決定其指向,需要開(kāi)發(fā)者在實(shí)際開(kāi)發(fā)中靈活應(yīng)用。
舉一個(gè)具體的例子,假設(shè)有一個(gè)對(duì)象 person,它有兩個(gè)方法 sayHello 和 introduce :
const person = {
name: "Quintion",
age: 32,
sayHello() {
console.log(`Hello, my name is ${this.name}`);
},
introduce() {
console.log(`I'm ${this.age} years old.`);
},
};
如果以方法調(diào)用的方式調(diào)用 sayHello() 和introduce():
person.sayHello(); // Hello, my name is Quintion
person.introduce(); // I'm 32 years old.
此時(shí) this 分別指向 person 對(duì)象,因?yàn)檫@兩個(gè)方法是在 person 對(duì)象中定義的。
如果以函數(shù)調(diào)用的方式調(diào)用 sayHello() 和introduce():
const sayHello = person.sayHello;
const introduce = person.introduce;
sayHello(); // Hello, my name is undefined
introduce(); // I'm undefined years old.
此時(shí) this 指向全局對(duì)象,因?yàn)楹瘮?shù)調(diào)用是在全局上下文中執(zhí)行的。由于全局對(duì)象并沒(méi)有 name 和 age 屬性,所以輸出結(jié)果為 undefined。
如果將上面的函數(shù)使用 call() 方法來(lái)調(diào)用,如下:
const sayHello = person.sayHello;
const introduce = person.introduce;
sayHello.call(person); // Hello, my name is Quintion
introduce.call(person); // I'm 32 years old.
此時(shí) this 指向 person 對(duì)象,因?yàn)樵?call() 方法的第一個(gè)參數(shù)中傳入了 person 對(duì)象。
需要注意的是,如果在嚴(yán)格模式下使用函數(shù)調(diào)用方式,
this指向的是undefined,而非全局對(duì)象。