Article Introduction: discusses the confusing keyword this, and how to determine and set the value of this. |
Today's tutorials come from a new book by Cody Lindley, the "JavaScript Initiation Tutorial/JavaScript Enlightenment". He discussed the confusing keyword this, as well as the method of determining and setting the value of this.
Conceptual Overview this
When a function is created, a keyword This is then created (in the background), which is linked to an object, and the function is manipulated in this object. In other words, the keyword This can be used in a function, a reference to an object, and a function is the property or method of that object.
Let's look at this object:
- <! DOCTYPE html>
- var cody = {
- Living:true,
- Age:23,
- Gender: ' Male ',
- Getgender:function () {return cody.gender;}
- };
- Console.log (Cody.getgender ()); Logs ' Male '
- </script></body>
Notice that in the function Getgender, because inside the Cody object, we can get the gender property (that is, Cody.gender). You can also use this to get the Cody object, because this is the point to the Cody object.
- <! DOCTYPE html>
- var cody = {
- Living:true,
- Age:23,
- Gender: ' Male ',
- Getgender:function () {return this.gender;}
- };
- Console.log (Cody.getgender ()); Logs ' Male '
- </script></body>
This.gender this points to the Cody object, and the Getgender function can manipulate the Cody object.
The subject of this may be a bit confusing, but it doesn't have to be. Just remember, usually, this point is the object that contains the function, not the function itself (with the exception of course, such as keyword New or call () and apply ()).
Important Tips
-keyword This is like the other variable, the only difference is that you can't change it.
-Unlike other arguments and variables passed to a function, this is a keyword (not a property) in the object that calls the function.
How do I determine the value of this?
This is passed to all functions, and its value depends on when the function runtime is invoked. Notice here, because this is a very special place you need to remember.
The MyObject object in the following code has a property sayfoo that points to the function Sayfoo. When you call the Sayfoo function in the global domain, this points to the Window object. When MyObject calls a function, this points to MyObject.
Because MyObject has a property called Foo, which is used here.
- <! DOCTYPE html>
- 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 Sayfoo function
- Myobject.sayfoo = Sayfoo;
- Myobject.sayfoo (); Logs ' I am Myobject.foo ' 12
- Sayfoo (); Logs ' Foo '
- </script></body>
It is clear that the value of this depends on when the function is invoked. Myobject.sayfoo and Sayfoo both point to the same function, but the Sayfoo () call has different contexts, and this is a different value. Here is a similar code, the Head Object (window) is explicitly used and hopefully useful to you.
- <! DOCTYPE html>
- 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>
Make sure that when you have multiple references pointing to the same function, you know clearly that the value of this is Tiaogan with the different context of the function.
Important Tips
-All variables and parameters except this are in the range of static variables (lexical scope).
Within the embedded function this points to the head object
You might want to know what happens when you use this in a function that is embedded in another function. Unfortunately in ECMA 3, this does not follow the rule, it does not point to the object to which the function belongs, but to the head object (the browser's Window object).
In the following code, this in Func2 and func3 no longer points to the MyObject, but the head object.
- <! DOCTYPE html>
- var foo = {
- Func1:function (BAR) {
- Bar (); Logs window, not foo
- Console.log (this);//the this keyword would be is a reference to Foo object
- }
- };
- FOO.FUNC1 (function () {Console.log (This)});
- </script></body>
However, in ECMAScript 5, this problem will be corrected. Now, you should be aware of this problem, especially when you pass the value of a function to another function.
Look at the following code, pass an anonymous function to FOO.FUNC1, and when the anonymous function is called in FOO.FUNC1 (the function is nested in another function), this will point to the head object in the anonymous function.
Now you will not forget that if the function containing this is in another function, or is called by another function, this value will point to the head object (again, this will be corrected in ECMAScript 5). )
Resolving problems with nested functions
In order for the value of this to not be lost, you can use a scope chain (scope chain) in the parent function to hold the reference to this. In the following code, using a variable called that, we can save the function context better by using its scope.
- <! DOCTYPE html>
- var myObject = {
- MyProperty: ' Icanseethelight ',
- Mymethod:function () {
- var that=this; Store a reference to this (I.e.myobject) in MyMethod scope varhelperfunctionfunction () {//childfunction
- var helperfunction function () {//childfunction
- Logs ' I can-light ' via scope chain because that=this
- Console.log (That.myproperty); Logs ' I Can the Light '
- Console.log (this); Logs Window object, if we don ' t use ' that '
- }();
- }
- }
- Myobject.mymethod (); Invoke MyMethod
- </script></body>
control the value of this
The value of this is usually dependent on the context of the calling function (unless you use the keyword new, which will be introduced later), but you can use apply () or call () to specify the object that this point points to when triggering a function to change/control the value of this. In both ways, it's like saying, "Hey, call the X function, but let the Z object do the value of this." "To do this, the JavaScript default of this value will be changed."
Next, we create an object and a function, and then we trigger the function by call (), so this in the function is pointing to myojbect. This in the MyFunction function operates MyObject instead of the head object, so we change the object that this point in myfunction.
- <! DOCTYPE html>
- var myObject = {};
- var myfunction = function (param1, param2) {
- Setviacall () ' This ' points to my Object when the 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>
In the above example, we use call (), apply () can also apply to the same use, the difference between the two is how the parameters passed to the function. With call (), the arguments are separated by commas, and the parameters are passed in an array using apply (). The following is the same code, but apply ().
- <! DOCTYPE html>
- var myObject = {};
- var myfunction = function (param1, param2) {
- Set via Apply (), this points to me Object 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>
Use this in a custom constructor
When the function is triggered with the keyword new, the value of this-because it is declared in the constructor-points to the instance itself. To put it another way: in a constructor, we can use this to specify the object before the object is actually created. It appears that the change of this value is similar to call () or apply ().
Below, we constructed a constructor person,this point to the object that was created. When the object of person is created, this points to the object and places the property name inside the object, which is the value of the parameter (name) passed to the constructor.
- <! DOCTYPE html>
- var person = function (name) {
- this.name = Name ' JohnDoe '; This is refer to the Instanc ecreated
- }
- var cody = new Person (' Cody Lindley '); Create a instance, based on person constructor
- Console.log (Cody.name); Logs ' Cody Lindley '
- </script></body>
Thus, when the constructor is triggered with the keyword new, this points to the object to create. So if we don't use the keyword new,this the value will point to the context that triggers the person--this is the head object. Let's take a look at the following code.
- <! DOCTYPE html>
- var person = function (name) {
- This.name=name ' JohnDoe ';
- }
- 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>
This
point within the prototype method points to the constructed instance
When a method is used as the prototype property of a constructor, this in this method points to an instance of the triggering method. Here, we have a constructor for person () that requires the full name of the person, in order to get full name. We have added a Whatismyfullname method to the Person.prototype, and all the person instances inherit the method. This in this method points to the instance that triggered the method (and its properties).
I created two person objects (Cody and Lisa) below, and the inherited Whatismyfullname method contains this to point to this instance.
- <! DOCTYPE html>
- 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'll look for it in the prototype chain.
- Below, we add a FullName property to both the person prototype and the Object
- Prototype. I'm here for your notes. */
- Object.prototype.fullName = ' John Doe ';
- var john = new Person (); No argument is passed so fullName are not added to instance
- Console.log (John.whatismyfullname ()); Logs ' John Doe '
- </script></body>
Using This,this in a method within a prototype object points to an instance. If the instance does not contain attributes, the prototype lookup begins.
Tips
-If this object does not contain the property that you want to find, then the law applicable to any attribute is also applicable here, that is, the property is "looking" along the prototype chain (prototype chain). So in our case, if the instance does not contain the FullName attribute, then fullName looks for Person.prototype.fullName and then Object.prototype.fullName.