This in javascript

Source: Internet
Author: User

This cannot be avoided in javascript, but the scope of this often sends changes inadvertently, leading to program errors or exceptions.
Here we only make some simple summary of this, and we need to consider more detailed behavior.
This is used in function functions (nonsense ...). It should be noted that the function in js is a common function (without a member function, which is accurate), no matter where it is defined.
Therefore, a function can be bound to any object. In this case, the bound object is the owner of the function. OK. this in the function points to its owner.
This is changeable because its owner often changes. For example:
<Script type = "text/javascript">
Var o = {
_ Name: 'O', // used for debug
Foo: function (){
Console. log (this. _ name );
}
}

O. foo ();
</Script>


Here o. foo is a function (which should be called a function pointer pointing to a function () {console. log (this. _ name );}). When o. foo () is executed, the owner of foo (which is actually the function indicated by foo) is o, and this in it is o, and the running result will print 'O ';
Why is it a function pointer? Continue with this example:
<Script type = "text/javascript">
Var fn = o. foo;
Fn ();
</Script>
Fn = o. foo does not enable o. the foo function is copied to fn, but to o. foo pointer value, so that fn also points to function funtion () {console. log (this. _ name );}.
What is the result of executing fn at this time? Fn (again, specifically the function pointed to by fn) "No" owner, then the system will pass the Global Object "window" to this, that is, the owner of fn (not again) is window.
Because the _ name attribute is not defined in the window, undefined is output. Test again and add a familiar _ name to the window;
<Script type = "text/javascript">
Window. _ name = 'window ';
Fn ();
</Script>
OK, the object to which this in the function actually points: the owner of the execution. Next, let's take a look at why this is unpredictable in actual applications.
The root cause is simple. His owner has changed, as shown in the preceding examples of o. foo and fn. The following are examples of frequent changes:
1. The functions in the object (you know this is not correct) Call the functions of other objects, and this will change.
<Script type = "text/javascript">
// For example, common ajax
Var o2 = {
Xhr: null,
Execute: function (){
Xhr. onreadystatuschange = function (){
This. _ traceXhr (xhr); // error here! 'Eas' is xhr now
}
},
_ TraceXhr: function (_ xhr ){
Console. log (_ xhr );
}
}
</Script>
The error here is obvious, function () {this. _ traceXhr (xhr);} is a function, which is bound to xhr for running at this time, where this naturally points to xhr instead of o2.
The correct method is o2. _ traceXhr (this); (ps, this may be true in actual applications. Generally, a "class" is defined. Oh, o2 is only an instance of this class, when defining a class, you need to write it like this:
<Script type = "text/javascript">
Function ClazzO (){
}

ClazzO. prototype. xhr = null;
ClazzO. prototype. execute = function (){
Var _ self = this;
Xhr. onreadystatuschange = function (){
_ Self. _ traceXhr (this );
}
}
ClazzO. prototype. _ traceXhr = function (_ xhr ){
Console. log (_ xhr );
}
</Script>
Execute saves the variable this with a temporary variable to prevent him from being found in onxxxchange.
This type of problem causes this change, and some are associated with dom objects.

2. this In the dom object event
A: <input type = "button" id = "a" onclick = "javascript: console. log (this. value)" value = "click me a"/>
The output result is the same as what we want: click this. However, some people have made some comments. It is not good to mix too many js Code in html, and sometimes the function is too complex to contain 'or ", so it cannot be written here, it is best to extract it and put it in a function:
B: <input type = "button" id = "B" onclick = "javascript: clicked ()" value = "click me B"/>
<Script type = "text/javascript">
Function clicked (){
Console. log (this. value );
}
</Script>
Let's see what the browser has done for us: onclick = "[js code]"
The browser will help us generate (I'm not sure about this, but it works in this way)
[Dom]. onclick = function () {[js code]}
Okay. Let's see what happened to both of the above:
<Script type = "text/javascript">
//
Document. getElementById ("a"). onclick = function (){
Console. log (this. value );
}
// B
Document. getElementById ("B"). onclick = function (){
Clicked ();
}
</Script>
The explanation is clear. Or the owner has changed

3. browser behavior
By the way, I can see the difference between the binding event of ie and ff (attachEvent and addEventListener). Let's continue to look at the example:
C: <input type = "button" id = "c" value = "click me c"/>
<Script type = "text/javascript">
Var c = document. getElementById ("c ");
If (document. attachEvent) {// for ie
C. attachEvent ('onclick', clicked );
} Else {
C. addEventListener ('click', clicked, false );
}
</Script>
Ie outputs undefined, ff outputs click me c, why? Add debug information and try again
D: <input type = "button" id = "d" value = "click me d"/>
<Script type = "text/javascript">
Function clicked2 (){
Console. log (this, arguments );
For (var I = 0; I! = Arguments. length; ++ I ){
Console. log ('arg ', I,': ', arguments [I]);
}
}
Var d = document. getElementById ("d ");
If (document. attachEvent) {// for ie
D. attachEvent ('onclick', clicked2 );
} Else {
D. addEventListener ('click', clicked2, false );
}
</Script>
See it. in ie, this is a window, and ff is the dom of the departure time. However, both of them will send an event parameter to clicked2.

From lazy Tom

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.