Javascript 的 this 用法

this 是 JavaScript 语言的一个关键字。

构造函数中的 this


在上一部分,我们使用了方法中的 this 来访问该方法所属的 对象。让我们再来看一个例子:

function Cat(name) {
this.name = name
this.lives = 9;
this.sayName = function () {
console.log( 'Meow! My name is ' + this.name);
};
}

const bailey = new Cat();

在上面的 Cat() 构造函数中,sayName 所指向的函数引用了 this.name。之前,我们已经看到过在方法中使用 this,但在这里,this 是指什么呢?

事实证明,当使用 new 运算符来调用构造函数时,this 会被设置为新创建的对象!让我们来看看新的 bailey 对象是什么样的:

{
name: Bailey,
sayName: function () {
console.log('Meow! My name is ' + this.name);
}
}

在以上代码段中,请注意 this 位于构造函数 外部。正如我们在上一篇文章中所看到的,当你说 this 时,你其实是在说“这个对象”或“当前对象”。因此,sayName() 方法可以使用 this 来访问该对象的 name 属性!这使得以下方法调用成为可能:

bailey.sayName();

// Meow! My name is Bailey

this 什么时候会被赋值?


一个常见的误解是,this 指向定义它的对象。事实并非如此!直到某个对象调用使用 this 的方法,this 才会被赋值。换句话说,赋给 this 的值取决于 调用定义 this 的方法的对象。让我们来看一个例子:

const dog = {
bark: function () {
console.log('Woof!');
},
barkTwice: function () {
this.bark();
this.bark();
}
};

让我们继续调用 dog 的两个方法:

dog.bark();
// Woof!

dog.barkTwice();
// Woof!
// Woof!

我们知道,当我们调用 dog.bark()dog.barkTwice() 时,变量 this 将被设置。由于 this 可以访问调用它的对象,因此 barkTwice 可以使用 this 来访问包含 bark 方法的 dog 对象。
但是,如果我们在 barkTwice 中使用 bark(),而不是 this.bark(),将会怎样?该函数会先在 barkTwice 的作用域内查找一个名为 bark 的局部变量。如果没有找到 bark,则会沿着作用域链继续查找。
综合来看:this.bark() 会告诉 barkTwice 查看 dog(调用该方法的对象)以查找 bark

this 会被设置为什么?


到目前为止,我们已经在许多不同的上下文中看到了 this,比如在方法中,或被构造函数引用。现在,让我们把它们放在一起来看一下!
有四种方式可以调用函数,而每种方式都会不同地设置 this

  • 首先,使用 new 关键字来调用构造函数会将 this 设置为一个新创建的对象。还记得吗,在我们之前创建 Cat() 的实例时,this 被设置为新的 bailey 对象。
  • 另一方面,调用属于一个对象的函数(即_方法_)会将 this 设置为该对象本身。回想一下前面的示例,dog 对象的 barkTwice 方法能够访问 dog 本身的属性。
  • 第三,单独调用一个函数(即简单地调用一个常规函数)将把 this 设置为 window。如果主机环境是浏览器,则它将是全局对象。
function funFunction() {
return this;
}

funFunction();
// (返回全局对象, `window`)
  • 第四种调用函数的方式可以让我们自己设置 this!现在不用在意这一点,我们将在下一部分进行深入探讨。
Call Style new method function
this {} object itself global object
Example new Cat() bailey.sayName() introduce()

如果使用 new 运算符来调用构造函数,this 的值将被设置为新创建的对象,如果在对象上调用方法,this 将被设置为该对象本身,如果简单地调用一个函数,this 将被设置为全局对象: window

小练习

请考虑以下构造函数 City

function City(name, population) {
this.name = name;
this.population = population;

this.identify = function () {
console.log(`${this.name}'s population is ${this.population}.`);
};
}

const sanFrancisco = new City('San Francisco', 870000); 被执行时,this 的值是什么?

答案: 新创建的对象,被 sanFrancisco 引用

请考虑以下对象 building

const building = {
floors: 5,
addFloor: function () {
this.floors += 1;
}
};

building.addFloor();

building.addFloor() 被执行时,this 的值是什么?

答案: building

当以下函数被调用时,this 的值是多少?

function myFunction() {
console.log("What is the value of 'this'?");
}

答案: window

小结


函数、对象和 this 彼此相互关联。当使用 new 运算符来调用构造函数时,this 变量会被设置为新创建的对象。当在对象上调用方法时,this 会被设置为该对象本身。当在浏览器环境中调用函数时,this 会被设置为 window,也被称为全局对象。

除此之外,还有一组方式可以调用函数:使用 apply() 和使用 call()。这两种方式有许多相似之处,每一种方式都允许我们指定如何设置 this。接下来,我们会对它们进行详细分析!

-------------本文结束 感谢您的阅读-------------
0%