Rumah >hujung hadapan web >tutorial js >Memahami kata kunci 'ini'.
Apabila anda mencipta fungsi, kata kunci yang dipanggil this
dicipta (di sebalik tabir) yang dipautkan kepada objek fungsi itu dijalankan. Dalam erti kata lain, ini
tersedia untuk skop fungsinya, tetapi ia adalah rujukan kepada objek yang fungsinya adalah sifat atau kaedah. this
的关键字(在幕后),该关键字链接到函数运行的对象。换句话说,this
可用于其函数的范围,但它是对该函数作为属性或方法的对象的引用。
让我们看一下上一篇文章中的 cody
对象:
示例:sample98.html
<!DOCTYPE html><html lang="en"><body><script> var cody = { living: true, age: 23, gender: 'male', getGender: function () { return cody.gender; } }; console.log(cody.getGender()); // Logs 'male'. </script></body></html>
注意在 getGender
函数内部,我们如何在 cody
对象本身上使用点表示法 (cody.gender
) 访问 gender
属性。可以使用 this
重写来访问 cody
对象,因为 this
指向 cody
对象。
示例:sample99.html
<!DOCTYPE html><html lang="en"><body><script> var cody = { living: true, age: 23, gender: 'male', getGender: function () { return this.gender; } }; console.log(cody.getGender()); // Logs 'male'. </script></body></html>
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
<!DOCTYPE html><html lang="en"><body><script> var foo = 'foo'; var myObject = { foo: 'I am myObject.foo' }; var sayFoo = function () { console.log(this['foo']); }; // Give myObject a sayFoo property and have it point to the sayFoo function. myObject.sayFoo = sayFoo; myObject.sayFoo(); // Logs 'I am myObject.foo'. sayFoo(); // Logs 'foo'. </script></body></html>
显然,this
的值基于调用该函数的上下文。考虑 myObject.sayFoo
和 sayFoo
都指向相同的函数。但是,根据调用 sayFoo()
的位置(上下文),this
的值会有所不同。
如果有帮助,这里是显式使用头对象(window
)的相同代码。
示例:sample101.html
<!DOCTYPE html><html lang="en"><body><script> window.foo = 'foo'; window.myObject = { foo: 'I am myObject.foo' }; window.sayFoo = function () { console.log(this.foo); }; window.myObject.sayFoo = window.sayFoo; window.myObject.sayFoo(); window.sayFoo(); </script></body></html>
确保当您传递函数或对函数进行多次引用时,您意识到 this 的值将根据您调用该函数的上下文而变化。
除 this
和 arguments
之外的所有变量都遵循词法范围
this
关键字引用嵌套函数中的头对象您可能想知道当 this
在一个包含在另一个函数中的函数内部使用时会发生什么。坏消息是在 ECMA 3 中,this
迷失了方向并引用了头对象(浏览器中的 window
对象),而不是定义该函数的对象。
在下面的代码中,func2
和 func3
中的 this
迷失了方向,并且不是指向 myObject
而是指向头对象。
示例:sample102.html
<!DOCTYPE html><html lang="en"><body><script> var myObject = { func1: function () { console.log(this); // Logs myObject. var func2 = function () { console.log(this) // Logs window, and will do so from this point on. var func3 = function () { console.log(this); // Logs window, as it’s the head object. } (); } (); } } myObject.func1(); </script></body></html>
好消息是,这个问题将在 ECMAScript 5 中得到解决。现在,您应该意识到这种困境,尤其是当您开始将函数作为值传递给其他函数时。
考虑下一个示例以及将匿名函数传递给 foo.func1
时会发生什么。当在 foo.func1
(函数中的函数)内部调用匿名函数时,匿名函数内部的 this
值将是对 head 对象的引用。
示例:sample103.html
<!DOCTYPE html><html lang="en"><body><script> var foo = { func1: function (bar) { bar(); // Logs window, not foo. console.log(this); // The this keyword here will be a reference to the foo object. } } foo.func1(function () { console.log(this) }); </script></body></html>
现在你永远不会忘记:当其宿主函数封装在另一个函数内或在另一个函数的上下文中调用时,this
值将始终是对头对象的引用(同样,这在 ECMAScript 5 中已修复) )。
为了使 this
值不会丢失,您可以简单地使用作用域链在父函数中保留对 this
的引用。以下示例演示了如何使用名为 that
Mari kita lihat objek
cody
daripada artikel sebelumnya: 🎜
🎜Contoh: sample98.html🎜
<!DOCTYPE html><html lang="en"><body><script> var myObject = { myProperty: 'I can see the light', myMethod : function(){ var that = this; // Store a reference to this (myObject) in myMethod scope. var helperFunction = function() { // Child function. // Logs 'I can see the light' via scope chain because that = this. console.log(that.myProperty); // Logs 'I can see the light'. console.log(this); // Logs window object, if we don't use "that". }(); } } myObject.myMethod(); // Invoke myMethod. </script></body></html>🎜Perhatikan bagaimana di dalam fungsi
getGender
kita mengakses gendercody.gender
) pada objek cody
itu sendiri /code > atribut. Anda boleh menggunakan penggantian ini
untuk mengakses objek cody
kerana ini
menghala ke objek cody
. 🎜
🎜Contoh: sample99.html🎜
<!DOCTYPE html><html lang="en"><body><script> var myObject = {}; var myFunction = function (param1, param2) { // Set via call(), 'this' points to myObject when function is invoked. this.foo = param1; this.bar = param2; console.log(this) // Logs Object {foo = 'foo', bar = 'bar'} }; myFunction.call(myObject, 'foo', 'bar'); // Invoke function, set this value to myObject. console.log(myObject) // Logs Object {foo = 'foo', bar = 'bar'} </script></body></html>🎜
this
yang digunakan dalam this.gender
hanya merujuk kepada objek cody yang mengendalikan fungsi tersebut. 🎜
🎜ini
digunakan di dalam fungsi untuk merujuk kepada objek yang terkandung oleh fungsi, dan bukannya fungsi itu sendiri (pengecualian termasuk menggunakan kata kunci new
atau call() dan apply()
). 🎜
🎜Kata kunci ini
kelihatan dan berkelakuan seperti mana-mana pembolehubah lain, kecuali anda tidak boleh mengubah suainya. 🎜
🎜Berbeza dengan argumen
dan sebarang hujah yang dihantar ke fungsi, ini
ialah kata kunci (bukan harta) dalam objek memanggil/mengaktifkan. 🎜
ini
ditentukan? ini
yang dihantar kepada semua fungsi adalah berdasarkan konteks di mana fungsi dipanggil pada masa jalan. Beri perhatian di sini, kerana ia adalah salah satu kebiasaan yang perlu anda ingat. 🎜
🎜Objek myObject
dalam contoh kod berikut diberikan sifat bernama sayFoo, yang menghala ke fungsi sayFoo
. Apabila fungsi sayFoo
dipanggil daripada skop global, ini
merujuk kepada objek window
. Apabila dipanggil sebagai kaedah myObject, ini
merujuk kepada myObject
. 🎜
🎜Memandangkan myObject
mempunyai sifat yang dipanggil foo
, gunakan sifat itu. 🎜
🎜Contoh: sample100.html🎜
<!DOCTYPE html><html lang="en"><body><script> var myObject = {}; var myFunction = function (param1, param2) { // Set via apply(), this points to myObject when function is invoked. this.foo = param1; this.bar = param2; console.log(this) // Logs Object {foo = 'foo', bar = 'bar'} }; myFunction.apply(myObject, ['foo', 'bar']); // Invoke function, set this value. console.log(myObject) // Logs Object {foo = 'foo', bar = 'bar'} </script></body></html>🎜Jelas sekali, nilai
myObject.sayFoo
dan sayFoo
kedua-duanya menghala ke fungsi yang sama. Walau bagaimanapun, nilai ini
akan berbeza bergantung pada lokasi (konteks) di mana sayFoo()
dipanggil. 🎜
🎜Jika ia membantu, berikut ialah kod yang sama menggunakan objek pengepala (<!DOCTYPE html><html lang="en"><body><script> var Person = function (name) { this.name = name || 'john doe'; // this will refer to the instance created. } var cody = new Person('Cody Lindley'); // Create an instance based on the Person constructor. console.log(cody.name); // Logs 'Cody Lindley'. </script></body></html>🎜Pastikan bahawa apabila anda lulus fungsi atau membuat beberapa rujukan kepada fungsi, anda sedar bahawa nilai ini akan berubah bergantung pada konteks di mana anda memanggil fungsi tersebut. 🎜 🎜Semua pembolehubah kecuali
argumen
menghormati skop leksikal🎜
ini
merujuk kepada objek pengepala dalam fungsi bersarangini
telah hilang dan merujuk objek pengepala (objek window
dalam penyemak imbas) dan bukannya objek di mana fungsi itu ditakrifkan. 🎜
🎜Dalam kod di bawah, ini
dalam func2
dan func3
hilang dan bukan menunjuk ke myObject
tetapi Menuding ke objek tajuk. 🎜
🎜Contoh: sample102.html🎜
<!DOCTYPE html><html lang="en"><body><script> var Person = function (name) { this.name = name || 'john doe'; } var cody = Person('Cody Lindley'); // Notice we did not use 'new'. console.log(cody.name); // Undefined. The value is actually set at window.name console.log(window.name); // Logs 'Cody Lindley'. </script></body></html>🎜Berita baiknya ialah masalah ini akan diselesaikan dalam ECMAScript 5. Sekarang, anda harus sedar tentang dilema ini, terutamanya apabila anda mula menghantar fungsi sebagai nilai kepada fungsi lain. 🎜 🎜Pertimbangkan contoh seterusnya dan perkara yang berlaku apabila anda menghantar fungsi tanpa nama kepada
foo.func1
. Apabila fungsi tanpa nama dipanggil di dalam foo.func1
(fungsi dalam fungsi), nilai ini
di dalam fungsi tanpa nama akan menjadi rujukan kepada objek kepala. 🎜
🎜Contoh: sample103.html🎜
<!DOCTYPE html><html lang="en"><body><script> var Person = function (x) { if (x) { this.fullName = x }; }; Person.prototype.whatIsMyFullName = function () { return this.fullName; // 'this' refers to the instance created from Person() } var cody = new Person('cody lindley'); var lisa = new Person('lisa lindley'); // Call the inherited whatIsMyFullName method, which uses this to refer to the instance. console.log(cody.whatIsMyFullName(), lisa.whatIsMyFullName()); /* The prototype chain is still in effect, so if the instance does not have a fullName property, it will look for it in the prototype chain. Next, we add a fullName property to both the Person prototype and the Object prototype. See the notes that follow this sample. */ Object.prototype.fullName = 'John Doe'; var john = new Person(); // No argument is passed so fullName is not added to the instance. console.log(john.whatIsMyFullName()); // Logs 'John Doe'. </script></body></html>🎜Sekarang anda tidak akan lupa: nilai
this
akan sentiasa menjadi rujukan kepada objek kepala apabila fungsi hosnya dibalut di dalam fungsi lain atau dipanggil dalam konteks fungsi lain (sekali lagi, ini Ditetapkan dalam ECMAScript 5)). 🎜
ini
tidak hilang, anda hanya boleh menggunakan rantai skop untuk menyimpan rujukan kepada ini
dalam fungsi induk. Contoh berikut menunjukkan cara menggunakan pembolehubah bernama itu
dan memanfaatkan skopnya, kita boleh menjejak konteks fungsi dengan lebih baik. 🎜
🎜Contoh: sample104.html🎜
<!DOCTYPE html><html lang="en"><body><script> var myObject = { myProperty: 'I can see the light', myMethod : function(){ var that = this; // Store a reference to this (myObject) in myMethod scope. var helperFunction = function() { // Child function. // Logs 'I can see the light' via scope chain because that = this. console.log(that.myProperty); // Logs 'I can see the light'. console.log(this); // Logs window object, if we don't use "that". }(); } } myObject.myMethod(); // Invoke myMethod. </script></body></html>
call()
或 apply()
控制 this
的值
this
的值通常由调用函数的上下文确定(除非使用 new 关键字,稍后会详细介绍),但您可以使用 this
的值>apply() 或 call()
来定义调用函数时 this
指向什么对象。使用这些方法就像在说:“嘿,调用 X 函数,但告诉该函数使用 Z 对象作为 this
的值。”通过这样做,JavaScript 确定 this
值的默认方式将被覆盖。
在下一个示例中,我们创建一个对象和一个函数。然后我们通过 call()
调用该函数,以便函数内 this
的值使用 myObject
作为其上下文。 myFunction
函数内的语句将使用属性填充 myObject
,而不是填充头对象。我们更改了 this
(在 myFunction
内部)引用的对象。
示例:sample105.html
<!DOCTYPE html><html lang="en"><body><script> var myObject = {}; var myFunction = function (param1, param2) { // Set via call(), 'this' points to myObject when function is invoked. this.foo = param1; this.bar = param2; console.log(this) // Logs Object {foo = 'foo', bar = 'bar'} }; myFunction.call(myObject, 'foo', 'bar'); // Invoke function, set this value to myObject. console.log(myObject) // Logs Object {foo = 'foo', bar = 'bar'} </script></body></html>
在前面的示例中,我们使用了 call()
,但也可以使用 apply()
。两者之间的区别在于函数参数的传递方式。使用 call()
,参数只是逗号分隔的值。使用 apply()
,参数值在数组内部传递,如以下示例所示。
示例:sample106.html
<!DOCTYPE html><html lang="en"><body><script> var myObject = {}; var myFunction = function (param1, param2) { // Set via apply(), this points to myObject when function is invoked. this.foo = param1; this.bar = param2; console.log(this) // Logs Object {foo = 'foo', bar = 'bar'} }; myFunction.apply(myObject, ['foo', 'bar']); // Invoke function, set this value. console.log(myObject) // Logs Object {foo = 'foo', bar = 'bar'} </script></body></html>
这里您需要学习的是,您可以覆盖 JavaScript 在函数作用域中确定 this
值的默认方式。
this
关键字当使用 new
关键字调用函数时,构造函数中声明的 this
的值指的是实例本身。换句话说:在构造函数中,我们可以在实际创建对象之前通过 this
来利用该对象。在这种情况下, this
的默认值的更改方式类似于使用 call()
或 apply()
。
在下面的示例中,我们设置了一个 Person
构造函数,该函数使用 this
来引用正在创建的对象。当创建 Person
的实例时,this.name
将引用新创建的对象,并在新对象中放置一个名为 name 的属性,并将参数 (name
) 中的值传递给构造函数。 p>
示例:sample107.html
<!DOCTYPE html><html lang="en"><body><script> var Person = function (name) { this.name = name || 'john doe'; // this will refer to the instance created. } var cody = new Person('Cody Lindley'); // Create an instance based on the Person constructor. console.log(cody.name); // Logs 'Cody Lindley'. </script></body></html>
同样,当使用 new
关键字调用构造函数时,this
指的是“将成为的对象”。如果我们没有使用 new
关键字,则 this
的值将是调用 Person
的上下文 - 在本例中为头对象。让我们看一下以下场景:
示例:sample108.html
<!DOCTYPE html><html lang="en"><body><script> var Person = function (name) { this.name = name || 'john doe'; } var cody = Person('Cody Lindley'); // Notice we did not use 'new'. console.log(cody.name); // Undefined. The value is actually set at window.name console.log(window.name); // Logs 'Cody Lindley'. </script></body></html>
this
引用构造函数实例当在添加到构造函数 prototype
属性的函数中使用时,this
指的是调用该方法的实例。假设我们有一个自定义 Person()
构造函数。作为参数,它需要人的全名。如果我们需要访问人员的全名,我们将 whatIsMyFullName
方法添加到 Person.prototype
中,以便所有 Person
实例继承该方法。当使用 this
时,该方法可以引用调用它的实例(以及它的属性)。
这里我演示了创建两个Person
对象(cody
和lisa
)以及继承的whatIsMyFullName
方法,其中包含this关键字来访问实例。
示例:sample109.html
<!DOCTYPE html><html lang="en"><body><script> var Person = function (x) { if (x) { this.fullName = x }; }; Person.prototype.whatIsMyFullName = function () { return this.fullName; // 'this' refers to the instance created from Person() } var cody = new Person('cody lindley'); var lisa = new Person('lisa lindley'); // Call the inherited whatIsMyFullName method, which uses this to refer to the instance. console.log(cody.whatIsMyFullName(), lisa.whatIsMyFullName()); /* The prototype chain is still in effect, so if the instance does not have a fullName property, it will look for it in the prototype chain. Next, we add a fullName property to both the Person prototype and the Object prototype. See the notes that follow this sample. */ Object.prototype.fullName = 'John Doe'; var john = new Person(); // No argument is passed so fullName is not added to the instance. console.log(john.whatIsMyFullName()); // Logs 'John Doe'. </script></body></html>
这里要带走的概念是 that
关键字 this 用于在 prototype
对象中包含的方法内部使用时引用实例。如果实例不包含该属性,则开始查找原型。
如果 this
指向的实例或对象不包含所引用的属性,则应用适用于任何属性查找的相同规则,并且将在原型链上“查找”该属性。因此,在我们的示例中,如果 fullName
属性未包含在我们的实例中,则将在 Person.prototype.fullName
中查找 fullName
属性,然后在 Object.prototype.fullName
中查找。
Atas ialah kandungan terperinci Memahami kata kunci 'ini'.. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!