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è)方法 sayHellointroduce

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)有 nameage 屬性,所以輸出結(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ì)象。