When you create a function, a keyword named this
is created (behind the scenes) which is linked to the object the function runs on. In other words, this
is available to the scope of its function, but it is a reference to the object whose function is a property or method.
Let’s take a look at the cody
object from the previous article:
Example: 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>
Notice how inside the getGender
function we access gender## using dot notation (
cody.gender) on the
cody object itself # Attributes. The
cody object can be accessed using the
this override because
this points to the
cody object.
<!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>
used in this.gender
simply refers to the cody object on which the function is operated.
The topic of
this may be confusing, but it isn't. Remember that, in general,
this is used inside a function to refer to the object contained by the function, rather than the function itself (exceptions include using the
new keyword or
call() and
apply()).
this looks and behaves like any other variable, except that you cannot modify it.
arguments and any arguments sent to the function,
this is a keyword (not a property) in the calling/activation object.
determined?
this passed to all functions is based on the context in which the function is called at runtime. Pay attention here, because it's one of those quirks you just need to remember.
myObject object in the following code example is assigned a property named sayFoo, which points to the
sayFoo function. When the
sayFoo function is called from the global scope,
this references the
window object. When called as a method of myObject,
this refers to
myObject.
myObject has a property named
foo, that property is used.
<!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 is based on the context in which the function is called. Consider
myObject.sayFoo and
sayFoo both point to the same function. However, depending on where (context)
sayFoo() is called, the value of
this will differ.
window).
<!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>
All variables except
this and
arguments follow lexical scope
Keyword refers to the header object in the nested function
this is used inside a function that is contained within another function. The bad news is that in ECMA 3,
this got lost and referenced the header object (the
window object in the browser) instead of the object where the function is defined.
this in
func2 and
func3 is lost and instead of pointing to
myObject header object.
<!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>
Consider the next example and what happens when you pass an anonymous function to
foo.func1. When an anonymous function is called inside
foo.func1 (a function within a function), the
this value inside the anonymous function will be a reference to the head object.
<!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 value will always be a reference to the head object when its host function is wrapped inside another function or called in the context of another function (again, this Fixed in ECMAScript 5)).
this value is not lost, you can simply use a scope chain to keep a reference to
this in the parent function. The following example demonstrates how using a variable named
that and leveraging its scope we can better track the function context.
<!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
中查找。
The above is the detailed content of Understanding the 'this' keyword. For more information, please follow other related articles on the PHP Chinese website!