Javascript this keyword Usage Analysis

Source: Internet
Author: User

I have read many articles about the this keyword in js. I wrote this article to analyze the working principle of this from an instance and hope it will be helpful to you.

I. Basic:

Copy codeThe Code is as follows:
Function doSomething (){
Alert (this. id );
}
Alert (window. doSomething); // proves that doSomething belongs to window.
DoSomething (); // undefined
Window. onload = function (){
Document. getElementById ("div2"). onclick = doSomething; // div2
Document. getElementById ("div3"). onclick = function () {doSomething ();} // undefined
}

1. For the doSomething function:
Copy codeThe Code is as follows:
Function doSomething (){
Alert (this. id );
}

This function is a global function, which actually belongs to the window (you can use window. doSomething to access). If you call this function directly, then according to "this always refers to the" owner "of the function we're re executing", then this in the function is window, however, the window does not have the id attribute, so "undefined" is displayed ";

2. Calling in html elements like this
Copy codeThe Code is as follows:
<Div id = "div1" onclick = "doSomething ();"> div1 </div>


"Undefined" is displayed, which is equivalent to the following code:
Copy codeThe Code is as follows:
Document. getElementById ("div1"). onclick = function () {doSomething ();}

When div1 is clicked, The doSomething function of the window is called, so "undefined" is displayed ";

3. Bind events through js. After div2 is loaded:
Copy codeThe Code is as follows:
Document. getElementById ("div2"). onclick = doSomething;

When div2 is clicked, "div2" is displayed. Because doSomething is copied once by assigning a value to div2 onclick, the copied function belongs to div2, it has nothing to do with doSomething of window. When div2 is clicked, The doSomething of div2 is triggered. this indicates div2.

2. attachEvent and addEventListener

AttachEvent is the method for binding events in ie. It copies the corresponding function to the global (that is, the owner of the response function is window), but in the DOM standard, the owner of the Response Function copied when the addEventListener is bound to an event is the object bound to the event.
Copy codeThe Code is as follows:
Function doSomething (){
Alert (this. id );
Alert (this = window );
}
Window. onload = function (){
Var div1 = document. getElementById ("div1 ");
If (div1.attachEvent ){
Div1.attachEvent ("onclick", doSomething );
Document. body. appendChild (document. createTextNode ("attachEvent "));
} Else if (div1.addEventListener ){
Div1.addEventListener ("click", doSomething, false );
Document. body. appendChild (document. createTextNode ("addEventListener "));
} Else {
Div. onclick = doSomething;
}
}


For the function doSomething
Copy codeThe Code is as follows:
Function doSomething (){
Alert (this. id );
Alert (this = window );
}

1. Bind The attachEvent to the div1 click Event, and doSometing will be copied to the window. this in doSomething refers to the window. When you click div1, "undefined" and "true" will be displayed"

2. Use addEventListener to bind the div1 click Event, and copy doSomething. The copied function belongs to div1. Therefore, "div1" and "false" are displayed when you click div1"

Note: accept:
Copy codeThe Code is as follows:
Var obj = new Object ();
Obj. color = "black ";
Obj. showColor = function (){
Alert (this. color );
Alert (this = window );
}
Obj. showColor ();

Var div1 = document. getElementById ("div1 ");
Div1.attachEvent ("onclick", obj. showColor );

When you click div1, "undefined" and "true" are displayed. If attachEvent only references obj. if showColor is used, this should still refer to obj, but in fact this refers to window, so I think this is not a reference, but a copy to the global one.

Iii. Inheritance methods of object impersonating

1. Differences between new and non-new

For the following functions
Copy codeThe Code is as follows:
Function ClassA (sColor ){
This. color = sColor;
This. sayColor = function (){
Alert (this. color );
}
}

Is this a class or a function? Depends on you!

If you think this is a function, we can call it like this:

ClassA ("red ");
"Red" is a passed parameter. this in ClassA refers to the window of course, so now window has the color attribute and sayColor method, and color has the value "red.

This is to call sayColor or window. sayColor to display "red ";

Window. sayColor ();


If you think this is a class, we should use it like this:

Var obj = new ClassA ("red ");
The emergence of the keyword "new" adds a lot of content to the above Code: first, create an Object instance, and then point this in ClassA to the created Object, finally, this Object is returned, so the returned Object is assigned to obj. So we can say that this points to obj. obj has the color attribute and sayColor method, and the color attribute value is "red ".

2. Function owener
Copy codeThe Code is as follows:
Function showId (){
Alert (this. id );
}
Window. onload = function (){
Var div1 = document. getElementById ("div1 ");
Div1.onclick = showId;
Div1.show = showId;
Div1.show ();

Var obj = new Object ();
Obj. id = "obj ";
Obj. show = showId;
Obj. show ();
}

We can assign the showId function to the click event, or assign a value to any attribute of any object. This will also copy the showId method, so when we call the div1.show method, this indicates div1. show, this points to obj.

3. Object impersonating Principle

The following code is the inheritance implemented through the object impersonating method.
Copy codeThe Code is as follows:
Function ClassA (sColor ){
This. color = sColor;
This. sayColor = function (){
Alert (this. color );
}
}

Function ClassB (sColor, sName ){
This. newMethod = ClassA;
This. newMethod (sColor );
Delete this. newMethod;

This. name = sName;
This. sayName = function (){
Alert (this. name );
}
}

Var objB = new ClassB ("color of objB", "name of objB ");
ObjB. sayColor ();

ObjB is an example of ClassB. How does objB possess the color attribute and the sayColor method?

First, we can see from the instantiated code:

Var objB = new ClassB ("color of objB", "name of objB ");

Here ClassB is a class, and this in ClassB is of course the objB object;

In ClassB, ClassA is used for the first three lines of code. In this case, ClassA is regarded as a function rather than a class.

If we call the ClassA function directly, it is clear that this in ClassA refers to the window object, so we first copy ClassA to the newMethod attribute of objB (this. newMethod = ClassA ),

Then call this. newMethod, this Is The owener of this method, and this in ClassB currently refers to objB, so in ClassA (strictly in newMethod, because this is copied, and ClassA is already two methods.) this refers to objB. In this way, the color attribute and sayColor method are assigned to objB through newMethod. Using the call and apply methods to implement inheritance is actually a principle. call and apply can be seen as the owner Method for changing methods, the first three sentences in ClassB serve this purpose.

4. Class. create in prototype1.6
Copy codeThe Code is as follows:
The Class. create method in prototype1.6 is roughly as follows:

Var Class = {
Create: function (){
//

Function klass (){
This. initialize. apply (this, arguments );
}

//

For (var I = 0; I <properties. length; I ++)
Klass. addMethods (properties [I]);

//

Return klass;
}
};

This is the case when using:


Copy codeThe Code is as follows:
Var Person = Class. create ({
Initialize: function (name ){
This. name = name;
},
Say: function (message ){
Alert (this. name + ":" + message );
}
});

Var aPerson = new Person ("name1 ");
APerson. say ("hello1 ");

The Person actually uses the Class. the klass returned by the create method (klass is a Class. the local variable in create is a function), Class. the parameters (initialize and say methods) passed by create are passed to the properties array in the create method and the klass prototype has these methods through the addMethods method. So the most important thing is what is hard to understand: What is this in klass. If you think about it, it is not difficult to get the answer. Person is actually a klass, and we use the new Keyword when instantiating the Person object:

Var aPerson = new Person ("name1 ");

This is equivalent

Var aPerson = new klass ("name1 ");

Although klass cannot be accessed outside, it can easily explain the problem. klass is a class rather than a simple function (we think so, because the new keyword is used ), this in klass refers to the declared instance. Here it is aPerson. aPerson can use the prototype of klass to own the initialize and say methods. In the new process, the code in klass will also be executed, so initialize will be executed during instantiation, that is, the constructor. (In klass, both this refer to aPerson. Why do I need to call it once through apply? This is mainly to pass the parameters of the constructor. You can use the apply method to Easily upload a number of parameters to the initialize method through arrays .)

5. analyze several examples

I will analyze the examples in other articles:

1. Run the following code:
Copy codeThe Code is as follows:
Function OuterFoo (){
This. Name = 'outer name ';

Function InnerFoo (){
Var Name = 'inner name ';
Alert (Name + ',' + this. Name );
}
Return InnerFoo;
}
OuterFoo ()();

The displayed result is "Inner Name, Outer Name"

OuterFoo is a function (not a class), so the first sentence

This. Name = 'outer name ';

This indicates the window object, so window. Name = 'outer name' after OuterFoo ';

And return InnerFoo. At this time, InnerFoo is also a function (not a class). When InnerFoo is executed, this also refers to window, so this in InnerFoo. the value of Name is "Outer Name" (window. name acts as a transfer station, allowing OuterFoo to pass the "Outer Name" value to InnerFoo), and the value of Name is the local variable "Inner Name"

2. Run the following code:


Copy codeThe Code is as follows:
Function JSClass (){

This. m_Text = 'division element ';
This. m_Element = document. createElement ('div ');
This. m_Element.innerHTML = this. m_Text;

If (this. m_Element.attachEvent)
This. m_Element.attachEvent ('onclick', this. ToString );
Else if (this. m_Element.addEventListener)
This. m_Element.addEventListener ('click', this. ToString, false );
Else
This. m_Element.onclick = this. ToString;
}

JSClass. prototype. Render = function (){
Document. body. appendChild (this. m_Element );
}

JSClass. prototype. ToString = function (){
Alert (this. m_Text );
Alert (this = window );
}

Window. onload = function (){
Var jc = new JSClass ();
Jc. Render ();
Jc. ToString ();
}

Click "division element" to display "undefined", "true" to ie, and "false" to other browsers ".

There is nothing to say about the instance declaration and call method. If the click event of an element is bound to an instance method, the method bound to it through addEventListener is copied, therefore, this indicates an html element. this element does not have the m_Text attribute (m_Text belongs to the JSClass instance, that is, the m_Text attribute belongs to jc). Therefore, click the element to display undefined, events bound to attachEvent will copy the function to the global state. this indicates the window object, and "undefined" will be displayed when you click an element ". Only when the jc. ToString () method is called, this indicates the jc object. Because jc has m_Text, "division element" can be displayed ".

Vi. Summary

In a code environment, how can I quickly find the object referred to by this? I want to pay attention to the following three aspects:
1. You must be clear about whether to copy or reference each function step (CALL)
2. Clearly know what the function owner is.
3. For a function, we need to figure out whether to use it as a function or as a class.

Supplement:
1. functions can be directly defined on instances and classes.
2. You cannot use prototype to define a function on an instance. You can only use prototype to define a function on a class.
3. functions directly defined on the class cannot use this to access the attributes of the object.
4. this can be used for functions created on the prototype of the class. this can be used for functions defined within the class, and the amount of functions created on the object instance can be this
Copy codeThe Code is as follows:
Window. alert = function (msg)
{
Document. write (msg + "<br> ");
}
Function say ()
{
This. f = "props ";
This. func3 = function () {alert ("f3," + this. f );}
}
Say. func1 = function () {alert ("func1," + this. f) ;}; // Error, a function defined directly on the class, cannot use this
Say. prototype. func2 = function () {alert ("func2," + this. f );}
Say. func1 ();
(New say (). func2 ();
Say. func2 (); // Error, a function defined by prototype must be instantiated before an object can be called.
Say. func3 (); // Error, a function defined on the class must be instantiated before it can be called.
(New say (). func3 ();
Var obj = {
Fld1: 10,
Func1: function (msg) {alert (msg );},
Func4: function () {alert (this. fld1 );}
}
Obj. prototype. func = function () {alert ("func") ;}; // prototype cannot be used to define objects in the Error instance.
Obj. func2 = function () {alert ("func2," + this. fld1) ;}; // OK, the function defined on the instance can use this to access the attributes of the object.
Alert (obj. fld1 );
Obj. func1 ("func1 ");
Obj. func2 ();
Obj. func4 ();

Javascript this usage Summary
Http://www.jb51.net/article/16863.htm

JavaScript this in-depth understanding
Http://www.jb51.net/article/19425.htm

Javascript this details object-oriented
Http://www.jb51.net/article/17584.htm

Javascript this pointer
Http://www.jb51.net/article/19434.htm

How to use this keyword in JavaScript
Http://www.jb51.net/article/7954.htm

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.