让我们一劳永逸地获得这个“ this”
积分:Pixabay.com

您对JavaScript的了解可以通过您对此的理解来很好地判断。 人们发现很难理解这一事实,是因为它在多种多样的场景中使用。

让我们一劳永逸地使它们正确。

如果我要从字面意义上谈论一点,它只是意味着-这件事就在我眼前。 “这件夹克很酷”,我姐姐手里拿着那件夹克。 我回答说:“不,这更好!” 我指的是我附近的夹克,她指的是她附近的夹克,因此是在各自的陈述中使用

此值取决于
1.执行上下文
2.调用

执行上下文

执行上下文是代码在其中运行的环境。 例如,一个函数的局部变量只能在该函数中访问,而不能在该函数外部访问。 这称为功能级别作用域或本地执行上下文。 在全局范围内声明的变量(在任何函数之外)都可以在所有基础函数中访问。 这称为全局执行上下文

让我们考虑这个示例,以了解它们之间的区别-

让我们一劳永逸地获得这个“ this”

在默认情况下,全局执行环境的价值是窗口对象。

让我们一劳永逸地获得这个“ this”

在任何本地上下文中, 值取决于函数的调用方式。

一,要求在全球范围内的功能将有它的这个值作为 window

让我们一劳永逸地获得这个“ this”

二。 调用运行JavaScript语句在严格模式下的函数必须以此未定义

让我们一劳永逸地获得这个“ this”

三, 调用对象内部的函数

让我们一劳永逸地获得这个“ this”

功能 add 是对象的属性之一 obj 当我们调用引用obj add 作为obj.add() ,它在obj的上下文中被调用。 属性abobj的上下文中具有确定的值因此定义了obj.add()结果。

cacheAdd变量存储add函数的引用。 如果我们稍后执行此函数,它将在调用它的上下文中运行。 在我们的示例中,我们在全局上下文中调用cacheAdd ,因此它将有一个全局对象作为this引用。 由于ab未在全局上下文中定义,因此我们将a+b的值设为NaN

为了证明这一点,让我们在全局上下文中定义ab

让我们一劳永逸地获得这个“ this”

obj.add()值为3,因为obj中定义的ab的值分别为1和2。 当我们将add缓存在变量中然后在全局上下文中执行后运行add ,由于a和b在全局上下文中的值分别为3和4,因此它的值为7。 因此,使用this函数的函数可能会根据执行上下文的不同而给出不同的结果。

让我们尝试另一个有趣的例子-

让我们一劳永逸地获得这个“ this”

在这种情况下,add函数返回另一个函数,并且在此内部函数中执行a+b的值。 obj.add()将返回一个具有一个console语句的函数。 因此,我们必须执行此返回的函数才能获得a&b的总和。 但是此返回的函数(在执行obj.add()返回)将在全局上下文中运行,因此a + b的值求值为7(全局上下文中a和b的值分别为3和4)。

让我们一劳永逸地获得这个“ this”

在这里,添加功能会在500ms超时后打印a和b的值。 setTimeout在全局上下文中运行。

为什么setTimeout在全局上下文中运行? (我将在下一篇文章中对此进行详细说明。)

需要调用该函数的直接对象的引用

让我们一劳永逸地获得这个“ this”

在这里, parentObj具有childObj作为属性之一,并且在childObj上定义了add函数。 当我们将add称为parentObj.childObj.add()时 ,add函数采用childObj引用,并且无法从childObj的本地上下文访问变量a和b。 因此a和b的值是不确定的

链接到原型链

如果我们实例化parentObj来创建childObj ,则可以在childObj上下文中访问其属性。

使用Object.create

让我们一劳永逸地获得这个“ this”

当在childObj的上下文中调用add函数时,它首先尝试在childObj的上下文中查找a,b和c的 ,如果未定义这些值中的任何一个,它将查找其父上下文,在这种情况下是parentObj

使用新的运算符

让我们一劳永逸地获得这个“ this”

在这种情况下,父级的属性在子级的上下文中可用。 正如我们在尾部控制台语句中看到的那样,子级的构造函数定义为Parent。 因此,它首先在被调用的上下文中检查值,然后查找其原型链。

这不是火箭科学!

默认情况下,代码在全局上下文中运行,即,它可以访问在window对象的上下文中定义的变量。 在上述每种情况下,我们仅将上下文限制为obj对象。 与之相关的所有操作都将以与上下文为window完全相同的方式执行。 即使在全局上下文中,如果未定义任何值,它也会查找原型链。

让我们一劳永逸地获得这个“ this”

如我们所见, toString函数是在obj __proto__属性中定义的,这意味着它是在Object的原型上定义的(因为obj是通过将new运算符应用于Object来创建的)。 作为toString 未在obj的上下文中定义,而是查找其原型链。

让我们在这里解决一个有趣的问题-

她姐姐顽固地拒绝与我分享糖果,并支持她的主张,她说,她是该糖果的所有者。

这是她的糖果-

让我们一劳永逸地获得这个“ this”

于是,不知何故,我已经修改this参考,她的作用whosCandyIsThis使用。 小孩子不知道JavaScript是一种非常规语言。 您可以随时按照自己的方式进行修改。

打电话,申请并绑定-我来了!

让我们一劳永逸地获得这个“ this”

使用这3个漂亮的功能,您可以修改参考的值。 在以上示例中, candy.whosCandyIsThis.call(myCandy) this修改 whosCandyIsThis参考whosCandyIsThis功能 myCandy

所谓的全部是什么?
call this引用显式传递给函数。 在这种情况下,它会告诉whosCandyisThis功能使用this作为myCandy

call的第一个参数是this引用,如果我们必须传递任何其他参数,则可以执行以下操作

 candy.whosCandyisThis.call(myCandy, true)` 

让我们再考虑一个示例:

让我们一劳永逸地获得这个“ this”

在这里,我们this引用显式传递给在hotel对象中定义的displayMenu函数,以相应地显示菜单。 (这很酷吗?)

但是,如果我想根据用户的位置显示菜单,该怎么办? 为此,我们将传递一个附加参数 displayMenu函数的location 让我们修改上面的代码以适合我们的要求。

让我们一劳永逸地获得这个“ this”

call的第一个参数是this引用,然后您可以传入任意数量的所需参数。 现在, displayMenu函数很好地显示了根据location参数的菜单项列表。 (听起来不错?)

apply操作方式与call相同,唯一的区别是传递参数的方式。 Apply将第一个参数作为与调用相同的引用作为引用,但其他参数将作为数组传递。

另一个可以修改this功能的功能 参考是bind 不像call apply 返回函数的结果, bind返回一个函数。 然后可以在以后的任何阶段调用此返回的函数。 它将在显式传递的bounded参数的上下文中运行。

让我们一劳永逸地获得这个“ this”

hotel.displayMenu.bind(ccd)返回具有this ccd引用的函数。 当我们运行boundFunction ,它将在ccd上下文中运行 因此在位置A上打印Espresso。

让我们一劳永逸地获得这个“ this”

我试图尝试自己的直觉。 如果我将已经绑定的函数绑定到其他引用,那么该函数是否可以在以后的绑定上下文中运行? 如果这是真的,我可以无休止地做到这一点,并尽我所能继续更改此参考! 这不是真的。 您只能将一个功能绑定一次。 在上面的示例中,我尝试再次用pizzaCentre绑定有界函数,但是当我执行此函数时,它将打印先前的结果,这意味着其引用仍指向第一个绑定( ccd )。

同样,JavaScript是一种非常规语言。 如果您可以自由修改任何东西,可以有保护完整性的守卫。 这样的杰作之一就是我们可爱的Arrow功能。

这就是它的工作方式。 简单明了。

让我们一劳永逸地获得这个“ this”

为什么我们在本文中甚至谈论箭头功能? 他们有什么特别之处?

在arrow函数中, this的值是其封闭的词法上下文的值
词法上下文是块级作用域。
它不会随callapplybind而改变

箭头函数保持其包围的词法上下文的绑定。

让我们一劳永逸地获得这个“ this”

黑纱! 这只肥箭夺走了我的糖果。

如您所见, whosCandyIsThis被定义为箭头函数。 因此它将保持其词法上下文的约束。 在实例化Candy时, niks为她的糖果设置了所有者和口味。 whosCandyIsThis 函数会绑定到niks参考。

因此,当我尝试通过使用调用,应用或绑定传递引用来显式调用它时,它将无法正常工作。 niks.whosCandyIsThis的绑定niks.whosCandyIsThis都无法更改niks.whosCandyIsThis功能!

您可能喜欢我之前有关服务人员的文章-

服务人员基础知识https://hackernoon.com/service-workers-62a7b14aa63a

构建Pokemon应用程序以评估浆果和服务人员的能力https://hackernoon.com/building-pokemon-app-to-evaluate-the-power-of-berries-service-worker-176d7c4e70e3

From: https://hackernoon.com/lets-get-this-this-once-and-for-all-f59d76438d34

相关文章: