"JS Basics" about this

Source: Internet
Author: User

The This keyword is a very special keyword in Javascript that is automatically defined in the scope of all functions. This provides a more elegant way to implicitly "pass" a reference to an object. For today, this is the point of this question.

This is done at run time, that is, when a function is called, rather than binding at the time of writing, and its context depends on the various conditions when the function is called. The binding of this and the position of the function declaration have no relation, only depending on where the function is called.

First, the call location

The called location is where the function is called. Finding this position is not a very simple matter, because sometimes the real call location is hidden.

All we have to do here is parse the call stack, that is, in order to get to all the functions called by the execution location, the call location we care about is in the previous call to the function that is currently executing.

As an example:

1 functionTest () {2     //the current call stack is test3     //so the current call position is global scope4     5Console.log ("Test");6     7Bar ();//where bar is called8 }9 Ten functionBar () { One     //the current call stack is test-a bar A     //so the current call location is in test -  -Console.log ("Bar"); theFoo ();//the call location of Foo - } -  - functionfoo () { +     //Current Call stack test-bar-Foo -     //so the call location is in bar +      AConsole.log ("foo"); at } -  -Test ();//the call location of test

Now that we know the call location, let's look at how it determines the bound object of this.

Ii. binding Rules

1. Default Bindings

The first thing to describe is the most common type of function call: a standalone function call. You can think of this rule as a default rule that cannot be applied to other rules.

Example:

1 function Test () {2     console.log (this3}4var a = 2; 5 // 2

A variable declared in the global scope (such as Var a=2) is a property of the same name for the global object, which is the window.a=2 in the browser environment;

Next, we can see that when we call Test (), THIS.A is parsed into a global variable A. Because in this case, test () is called directly using a function reference without any adornments, and the default rule is applied, and this points to the global object.

One thing to note here is that if you use strict mode (strict modes), you cannot use a global object for the default binding, so this is bound to undefined.

Example:

1 function Test () {2     "use strict"; 3     Console.log (this. a); 4 }5var a = 2; 6 // typeerror:this is undefined

But here's a very important detail. Although this binding rule depends entirely on the call location, the default binding is bound to the global object only if test () is running under non-strict mode, and the default binding is not affected by the strict mode down test ().

Example:

1 function Test () {2     console.log (this. a)3}4var a =2; 5 (function() {6     "use strict"; 7     // 2 8 }) ()

Compare the two examples above to find the difference between this application default binding in different strict mode.

2. Implicit binding

Another rule to consider is whether the call location has a context, or whether it is owned or contained by an object.

Example:

  1  function   Test () {  2  console.log (this  .a)   3  }   4   5  var  obj = {  6  a:2< Span style= "COLOR: #000000",   7   test:test< /span> 8  };   9  10  obj.test (); //  2  

When test () is called, it is preceded by a reference to obj. When a function refers to a context object, an implicit binding rule binds this to the context object in the function call. In this case, the test () is called when this is bound to obj, so THIS.A is obj.a.

There are two points to note in an implicit binding:

A, the object attribute reference chain has only the previous layer, or the last layer in the call function.

Example:

1 functionTest () {2Console.log ( This. A)3 }4 5 varobj = {6A:2,7 test:test8 };9 Ten varObj_1 = { OneA:4, A Obj:obj - } -  theObj_1.obj.test ();//2

b, implicit loss. The implicitly bound function loses the bound object, that is, the default binding is applied, which binds this to the global object or to the undefined (in the case of strict mode).

Example:

1 functionTest () {2Console.log ( This. A)3 }4 5 varobj = {6A:2,7 test:test8 };9 Ten varFoo =obj.test; One  A varA = 4; -  -Foo ();//4

The Foo here actually refers to the test function itself when executing var foo = obj.test; , the reference address of obj.test to test is copied to Foo, which means that Foo and obj.test point to the same reference address. So calling Foo is actually a function call without any adornments, with the default binding applied. References to replication if it's still not quite clear. You can look at the first part of the http://www.cnblogs.com/lijiayi/p/jsdeeepcopy.html in the basic type and the reference type.

3. Display Bindings

This is mainly referred to by call (), apply () function calls, the implementation of the binding method.

Their first argument is an object that is prepared for this, and then binds it to this when the function is called. Because you can specify this binding object directly, it is called display binding.

Example:

1 function Test () {2     console.log (this. a)3}45 var obj = {6     a:27}; 8 9 // 2

With Test.call (), we can force the this to be bound to obj when we call test.

Here's a bit more: if you pass in a primitive value (string type, Boolean or numeric type) as the bound object of this, the original value is converted to its object form (that is, new string (), new Boolean (), or new number ()). This is often referred to as "boxing".

One thing to be aware of in the display bindings:

Show bindings in call apply or bind in the null or undefined, these values are ignored when invoked, and the default bindings are actually applied.

Example:

1 function Test () {2     console.log (this. a)3}4var a = 2; 5 Test.call (null//  2

You might think, how could I send a null?

A very common practice is to "expand" an array with apply and pass in a function as a parameter.

Example:

1 function Test (b) {2     console.log ("A:" + A + ", B:" + B)3}4 foo.apply ( NULL // A:2,b:3

Another option is to use bind to curry parameters (set some parameters beforehand)

Example:

1 function Test (b) {2     console.log ("A:" + A + ", B:" + B)3}45 var bar = Test.bind (null, 2); 6 // A:2,b:3

Both of these methods need to pass in a parameter as the binding object of this, but if the function does not relate to this, you still need a value, then null may be a good choice.

4. New Binding

The following actions are performed automatically when you use new to invoke a function, or when a constructor call occurs.

A, create (or construct) a completely new object.

b, this new object will be executed [[prototype]] connection.

C, this new object is bound to this of the function call.

D, if the function does not return other objects, the function in the new expression will automatically return to the newly-returned object.

Example:

1 function Test (a) {2    this. A = a3}45varnew Test (2); 6 // 2

When you call Test () with new, we construct a new object and bind it to this on the test () call.

Third, priority

Now that you know the four rules for this binding, what if you can apply more than one rule to a call location?

Here we say the priority of the above four rules:

New binding > Show Bindings > Implicit binding > Default Bindings

Summary: When we hit this, we find the call location, and then apply the call rule in the following order:

1. Is the function called in New, which is the application's new binding? If so, this binds to the newly created object.

var new test ();

2. Is the function called by call and apply, that is, the application shows bindings? If so, this binds to the specified object.

Test.call (obj)

3, whether the function is called in a context, that is, the application of implicit binding? If so, this is the context object that this binding is.

Obj.test ()

4, if not, use the default bindings. If in strict mode, bind to undefined, otherwise bind to the global object.

Test ()

Iv. this in the ES6

A special function type that cannot be applied to these rules is used in ES 6: arrow functions.

The arrow functions are not defined using the Function keyword, but are defined using the operator, known as the "Fat arrow". The arrow function does not use the four standard rules of this, but rather determines this based on the outer (function or global) scope.
Example:

1 functionTest () {2     return(a) = ={3Console.log ( This. A)4     }5 }6 7 varObj1 = {8A:29 }Ten  One varObj2 = { AA:4 - } -  the varBar =Test.call (obj1); -Bar.call (OBJ2);//2, not 4! 

The arrow function created inside test captures this of the call Test (). Because the this of test is bound to obj 1,bar (reference arrow function) This is also bound to obj 1, the binding of the arrow function cannot be modified (new is not available). The arrow function inherits the this binding of the outer function call.

Reference and thanks:

You don't know the JavaScript (roll up) (fried chicken recommended for everyone to see)

"JS Basics" about this

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.