this
是 JavaScript 语言的一个关键字。
构造函数中的 this
在上一部分,我们使用了方法中的 this
来访问该方法所属的 对象。让我们再来看一个例子:
function Cat(name) { |
在上面的 Cat()
构造函数中,sayName
所指向的函数引用了 this.name
。之前,我们已经看到过在方法中使用 this
,但在这里,this
是指什么呢?
事实证明,当使用 new
运算符来调用构造函数时,this
会被设置为新创建的对象!让我们来看看新的 bailey
对象是什么样的:
{ |
在以上代码段中,请注意 this 位于构造函数 外部。正如我们在上一篇文章中所看到的,当你说 this 时,你其实是在说“这个对象”或“当前对象”。因此,sayName()
方法可以使用 this 来访问该对象的 name
属性!这使得以下方法调用成为可能:
bailey.sayName(); |
this 什么时候会被赋值?
一个常见的误解是,this 指向定义它的对象。事实并非如此!直到某个对象调用使用 this 的方法,this 才会被赋值。换句话说,赋给 this 的值取决于 调用定义 this 的方法的对象。让我们来看一个例子:
const dog = { |
让我们继续调用 dog
的两个方法:
dog.bark(); |
我们知道,当我们调用 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() { |
- 第四种调用函数的方式可以让我们自己设置 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) { |
当 const sanFrancisco = new City('San Francisco', 870000)
; 被执行时,this
的值是什么?
答案: 新创建的对象,被 sanFrancisco
引用
请考虑以下对象
building
:
const building = { |
当 building.addFloor()
被执行时,this
的值是什么?
答案: building
当以下函数被调用时,this 的值是多少?
function myFunction() { |
答案: window
小结
函数、对象和 this
彼此相互关联。当使用 new
运算符来调用构造函数时,this
变量会被设置为新创建的对象。当在对象上调用方法时,this
会被设置为该对象本身。当在浏览器环境中调用函数时,this
会被设置为 window
,也被称为全局对象。
除此之外,还有一组方式可以调用函数:使用 apply()
和使用 call()
。这两种方式有许多相似之处,每一种方式都允许我们指定如何设置 this
。接下来,我们会对它们进行详细分析!