掌握 JavaScript 中的“this”
简而言之,“这”是什么
#规则 1. 默认绑定
规则2.隐式绑定
规则3.显式绑定
规则4. 新的绑定
规则5. 词汇绑定
结论
感谢信
在本文中,我们介绍了 JavaScript 中非常重要但又令人困惑的主题——“ this ”关键字。
TL;DR
如果“ this ”让你感到害怕,别担心!我们将学习如何使用五个简单的规则来确定“ this ”关键字的值。
这五条简单规则如下:
- 常规方法—— 默认绑定
- 对象内部的函数——隐式绑定
- 函数借用——显式绑定
- 使用函数创建对象——新绑定
- 箭头函数与常规函数的区别—— 词汇绑定
别担心这些吓人的名字。计算机科学的人喜欢把术语命名得像外星生物一样。其实,它们只是一些普通的概念,任何愿意理解的人都能理解。
this变量对应于函数的调用方式。这些规则帮助我们在各种情况下确定this的值。
一旦你理解了这些规则,你就不会再害怕它们了。
在我们开始之前,请先阅读本文以了解其工作原理。
简而言之,“这”是什么
在 JavaScript 中,每当调用一个函数时,JavaScript 引擎都会创建一个新的执行上下文。该执行上下文会一直存在,直到函数执行完毕。每个执行上下文都包含一个名为“this”的变量。
#规则 1. 默认绑定
当以上面所示的标准方式调用函数时,“ this ”实际上将引用全局对象!
在浏览器中,全局对象意味着Window对象。
需要记住的一个例外是启用严格模式时。通过编写“use-strict”,您可以阻止在全局对象上声明任何内容。
规则2.隐式绑定
如果函数包含在一个对象中,那么该对象将被“this”引用。
对于上述内容,this关键字将指向personObj
规则3.显式绑定
我们了解了this指向全局对象的指针,以及在另一种情况下,它指向包含它的对象。如果能够在函数调用时控制这个变量的最终结果,岂不是很棒?
像call、apply和bind这样的词通常会让新开发者感到恐惧。实际上,它们都是可以用来显式设置 this 值的函数。
让我们通过一个例子来理解它。
假设我们有两个对象,personObj假设readerObj
两个对象都有一个 name 属性。personObj有一个可以打印 内部值的函数name,但是 却readerObj没有任何这样的功能!
这里我们可以使用以下三种方法之一—— call,apply或bind。
这个过程称为功能借用。
我们借用sayName了readerObj.
现在我们可以打印 name 属性readerObj
sayName我们从调用方法personObj,但同时,我们指示 JavaScript 引擎sayName方法中的“this”变量应该指向readerObj。
所以当JavaScript引擎执行代码时,函数中的thissayName变量不是指向personObj而是指向readerObj。
这有道理吗?
不仅如此——我们还可以在使用该call函数时传递一些参数。
我们通过 Namaste 作为论据
我们可以在方法中利用参数sayName。
当我们执行代码时,我们将获得输出以及传递的参数。
apply 方法的工作方式相同,但它不是以常规参数为参数,而是以数组为参数。
bind 方法也以相同的方式工作——它可以接受常规参数。
但与call和apply不同 ——bind返回一个函数——该函数可以存储在变量中并可以在将来执行。
我们可以看到在函数柯里化中使用 bind —— 这个主题我们将在以后介绍。
规则4. 新的绑定
我们使用new关键字来创建对象的实例或副本。new 关键字的作用是:
- 它创建一个空对象,然后指示关键字this指向该空对象。
return this然后它在该函数的末尾添加一个语句。
请记住,当使用new关键字创建对象实例时,“ this ”始终指向新创建的实例。
让我们通过一个例子来理解这一点。
当我们运行此代码时,我们应该得到什么?
正如我们所说的——一个空的对象!
幕后发生的事情是
什么?我们要调用这个函数吗?
是的!
瞧,我告诉过你它正在被调用。
让我们来看一下事情的整个经过。
如果我们在函数中放入一些值,它会将其放入新创建的对象中然后返回它!
当我们console.log(newPersonObj)
让我们用动画来完成这个概念。
由于dev.to仅支持 500 帧的动画,因此我附加了动画的外部链接,
点击此处查看动画
在上面的例子中,我们使用一个函数来创建一个对象。
这种类型的函数称为函数构造函数。
请记住,在newPersonObj存储副本的中personObj,“this”变量指向空personObj
现在有意义了吗?
好!现在让我们了解最后一条规则。
规则5. 词汇绑定
随着 ES6 的出现,我们迎来了箭头函数。箭头函数以其极其精简的语法,自然而然地取代了传统的匿名函数。
要显式调用箭头函数,就像常规匿名函数一样,您需要先将其分配给变量:
箭头函数就像常规匿名函数一样,但有一个主要例外——函数内部此对象的行为。
在常规函数中,“ ”的值this是基于上下文的 - 在链接内调用该函数,“ this”指向链接的对象;在另一个函数内调用它setInterval(),则“ this”指向全局窗口对象。
例如,以下示例尝试调用start()自定义对象的方法,使其计数器属性每秒增加 1,但由于对“ this”对象引用计数器的错误假设而失败。
上述代码this.counter未能正确引用对象的 counter 属性countup,尽管这个错误可能不太容易发现。人们可能会错误地或粗心地认为“ this”指向该countup对象,但实际上它指向的是全局window对象,因为上下文“ this”在全局 window 方法中被调用setInterval()。
结果是指向一个不存在的属性的引用,当我们尝试增加它时,window.counter它会重复返回。为了在匿名函数中正确引用该对象,我们应该在上下文更改为其他对象之前缓存对正确“ ”对象的引用:NaNcountupthis
箭头函数内的“ this”对象是词法绑定的,这只是一种奇特的说法,即它的值是静态的,并且由“ this”关键字的定义位置决定。
与常规函数相比,“ ”是动态的,并且基于上下文调用它,而不管定义this“ ”时的范围如何。this
让我们以前面那个给我们带来麻烦的例子为例,看看如何通过改用箭头函数来直观地解决问题:
我们仅使用箭头函数就解决了这个问题。
结论
如果你理解了所有规则,那就拍拍自己的肩膀吧——这是你应得的!现在你不再害怕 JavaScript 中最令人困惑的概念——“ this ”关键字了。
在本文中我们了解到:
- 当以上面所示的标准方式调用函数时,“ this ”实际上将引用全局对象!
- 如果函数包含在一个对象中,那么“ this ”将指向该对象。
- call、 apply和bind是 JavaScript 提供给我们的函数,用来改变程序中“ this ”的行为。
- new关键字或运算符用于创建一个空对象,然后指示“ this”指向新创建的对象
- 箭头函数使我们能够在程序中词法绑定“ this
this”关键字,这意味着它的值是静态的,并且由“ ”关键字定义的位置决定。
感谢信
我想借此最后一次机会向您表示感谢。
谢谢你来看我!如果没有像你这样的人一直关注我,并勇敢地阅读我的帖子,我不可能取得今天的成就。
希望您能关注我未来的博客文章,并持续关注,因为我认为我们这里有一些很棒的内容。也希望在未来的岁月里,我能在您的职业生涯中为您提供帮助!
下次再见。再见!
文章来源:https://dev.to/polymathsomnath/master-this-in-javascript-1bk
后端开发教程 - Java、Spring Boot 实战 - msg200.com




























