理解“this”关键字

PHPz
Lepaskan: 2023-08-30 17:05:09
asal
874 orang telah melayarinya

理解“this”关键字

创建函数时,会创建一个名为this的关键字(在幕后),该关键字链接到函数运行的对象。换句话说,this可用于其函数的范围,但它是对该函数作为属性或方法的对象的引用。

让我们看一下上一篇文章中的cody对象:

示例:sample98.html

Salin selepas log masuk

注意在getGender函数内部,我们如何在cody对象本身上使用点表示法 (cody.gender) 访问gender属性。可以使用this重写来访问cody对象,因为this指向cody对象。

示例:sample99.html

Salin selepas log masuk

this.gender中使用的this只是指操作该函数的 cody 对象。

this的主题可能会令人困惑,但事实并非如此。请记住,一般来说,this在函数内部使用来引用该函数所包含的对象,而不是函数本身(例外情况包括使用new关键字或call()应用())。

关键字this的外观和行为与任何其他变量类似,只是您无法修改它。

arguments和发送到函数的任何参数相反,this是调用/激活对象中的关键字(而不是属性)。


this的值是如何确定的?

传递给所有函数的this的值基于运行时调用该函数的上下文。请注意这里,因为这是您只需要记住的怪癖之一。

以下代码示例中的myObject对象被赋予一个名为 sayFoo 的属性,该属性指向sayFoo函数。当从全局范围调用sayFoo函数时,this引用window对象。当作为 myObject 的方法调用时,this指的是myObject

由于myObject有一个名为foo的属性,因此使用该属性。

示例:sample100.html

Salin selepas log masuk

显然,this的值基于调用该函数的上下文。考虑myObject.sayFoosayFoo都指向相同的函数。但是,根据调用sayFoo()的位置(上下文),this的值会有所不同。

如果有帮助,这里是显式使用头对象(window)的相同代码。

示例:sample101.html

Salin selepas log masuk

确保当您传递函数或对函数进行多次引用时,您意识到 this 的值将根据您调用该函数的上下文而变化。

thisarguments之外的所有变量都遵循词法范围


this关键字引用嵌套函数中的头对象

您可能想知道当this在一个包含在另一个函数中的函数内部使用时会发生什么。坏消息是在 ECMA 3 中,this迷失了方向并引用了头对象(浏览器中的window对象),而不是定义该函数的对象。

在下面的代码中,func2func3中的this迷失了方向,并且不是指向myObject而是指向头对象。

示例:sample102.html

Salin selepas log masuk

好消息是,这个问题将在 ECMAScript 5 中得到解决。现在,您应该意识到这种困境,尤其是当您开始将函数作为值传递给其他函数时。

考虑下一个示例以及将匿名函数传递给foo.func1时会发生什么。当在foo.func1(函数中的函数)内部调用匿名函数时,匿名函数内部的this值将是对 head 对象的引用。

示例:sample103.html

Salin selepas log masuk

现在你永远不会忘记:当其宿主函数封装在另一个函数内或在另一个函数的上下文中调用时,this值将始终是对头对象的引用(同样,这在 ECMAScript 5 中已修复) )。


利用作用域链解决嵌套函数问题

为了使this值不会丢失,您可以简单地使用作用域链在父函数中保留对this的引用。以下示例演示了如何使用名为that的变量并利用其作用域,我们可以更好地跟踪函数上下文。

示例:sample104.html

Salin selepas log masuk

使用call()apply()控制this的值

this的值通常由调用函数的上下文确定(除非使用 new 关键字,稍后会详细介绍),但您可以使用this的值>apply()或call()来定义调用函数时this指向什么对象。使用这些方法就像在说:“嘿,调用 X 函数,但告诉该函数使用 Z 对象作为this的值。”通过这样做,JavaScript 确定this值的默认方式将被覆盖。

在下一个示例中,我们创建一个对象和一个函数。然后我们通过call()调用该函数,以便函数内this的值使用myObject作为其上下文。myFunction函数内的语句将使用属性填充myObject,而不是填充头对象。我们更改了this(在myFunction内部)引用的对象。

示例:sample105.html

Salin selepas log masuk

在前面的示例中,我们使用了call(),但也可以使用apply()。两者之间的区别在于函数参数的传递方式。使用call(),参数只是逗号分隔的值。使用apply(),参数值在数组内部传递,如以下示例所示。

示例:sample106.html

Salin selepas log masuk

这里您需要学习的是,您可以覆盖 JavaScript 在函数作用域中确定this值的默认方式。


在用户定义的构造函数中使用this关键字

当使用new关键字调用函数时,构造函数中声明的this的值指的是实例本身。换句话说:在构造函数中,我们可以在实际创建对象之前通过this来利用该对象。在这种情况下,this的默认值的更改方式类似于使用call()apply()

在下面的示例中,我们设置了一个Person构造函数,该函数使用this来引用正在创建的对象。当创建Person的实例时,this.name将引用新创建的对象,并在新对象中放置一个名为 name 的属性,并将参数 (name) 中的值传递给构造函数。

示例:sample107.html

Salin selepas log masuk

同样,当使用new关键字调用构造函数时,this指的是“将成为的对象”。如果我们没有使用new关键字,则this的值将是调用Person的上下文 - 在本例中为头对象。让我们看一下以下场景:

示例:sample108.html

Salin selepas log masuk

原型方法中的关键字this引用构造函数实例

当在添加到构造函数prototype属性的函数中使用时,this指的是调用该方法的实例。假设我们有一个自定义Person()构造函数。作为参数,它需要人的全名。如果我们需要访问人员的全名,我们将whatIsMyFullName方法添加到Person.prototype中,以便所有Person实例继承该方法。当使用this时,该方法可以引用调用它的实例(以及它的属性)。

这里我演示了创建两个Person对象(codylisa)以及继承的whatIsMyFullName方法,其中包含this关键字来访问实例。

示例:sample109.html

Salin selepas log masuk

结论

这里要带走的概念是that关键字 this 用于在prototype对象中包含的方法内部使用时引用实例。如果实例不包含该属性,则开始查找原型。

如果this指向的实例或对象不包含所引用的属性,则应用适用于任何属性查找的相同规则,并且将在原型链上“查找”该属性。因此,在我们的示例中,如果fullName属性未包含在我们的实例中,则将在Person.prototype.fullName中查找fullName属性,然后在Object.prototype.fullName中查找。

Atas ialah kandungan terperinci 理解“this”关键字. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!