If you ask the beginner JS what is more difficult to understand, many answers will be the This keyword. This is different from the different scenes of the object, there is a confusing feeling, Buddha magic is generally mysterious: what is this? There are four kinds of binding rules here.
1. Default Bindings
The default binding is the way that other calling rules cannot be applied when they are bound, see the following code:
1 var a = 1; 2 3 function foo () {4 console.log (this. a); 5 }67// 1
1 "use strict"23var a = 1; 4 5 function foo () {6 console.log (this. a); 7 }89// Typeerror:cannot Read Property ' A ' of undefined
This is the most basic function call, in the first diagram, in the non-strict mode, this is bound to the global object, so THIS.A points to global variable A. In the second picture, in strict mode, the global object cannot use the default binding, so this is bound to undefined.
So how to judge is the default binding, actually very simple, we look at the invocation of Foo, where Foo is called directly, Foo is not referenced to any other object or is explicitly bound to the specified object (explicit binding will be described later), so only the default binding rules can be used.
2. Implicit binding
Implicit binding takes into account whether the call location has a context object, or is sufficient to be contained or owned by an object, such as the following code:
1 function Foo () { 2 console.log (this .a); " 4 5 var obj = { 6 a:1, 7 Foo:foo 8 }; 10 Obj.foo (); //
When you declare obj, it contains foo, so when you call Obj.foo (), this binding to OBJ,THIS.A is obj.a. If there are multiple levels of containment, this is bound to the last level of the context object, such as the following code:
1 functionfoo () {2Console.log ( This. a);3 }4 5 varObj2 = {6A:2,7 Foo:foo8 };9 Ten varObj1 = { OneA:1, A Obj2:obj2 - }; - theObj1.obj2.foo ();//2
This will bind to the OBJ2.
There is also a situation, called implicit binding is missing, see the following code:
1 functionfoo () {2Console.log ( This. a);3 }4 5 varobj = {6A:1,7 Foo:foo8 };9 Ten varA = ' global '; One A varBar =Obj.foo; - -Bar ();//Strict mode is the undefined, the non-strict mode is the global
This specifies that bar is an alias (or reference) for Obj.foo, but it is important that bar actually refers to Foo itself, so calling bar () here is equivalent to a default binding, which applies to the default binding rule described above. If you do need a function alias and bind this to the specified object, you can use explicit binding, such as bind, call, apply, and so on, which will be discussed later.
Implicit binding loss also occurs when a callback function is passed in:
1 functionfoo () {2Console.log ( This. a);3 }4 5 functionCaller (func) {6 func ();7 }8 9 varobj = {TenA:1, One Foo:foo A }; - - varA = ' global '; the -Caller (Obj.foo);//Strict mode is the undefined, the non-strict mode is the global
In the front-end of JS programming, because it is event-driven, call callback function often occurs after user interaction, due to the loss of the binding, we often need to manually bind this to an object.
3. Explicit binding
If we want to force the invocation of a function on an object, we can use explicit binding. The prototype of a function in JS is a functions object, which provides some common methods. In terms of explicit binding, we can use both the Apply and call methods, with the following specific uses:
1 func.apply (obj, [arg1, arg2,...]); 2 func.call (obj, arg1, arg2,...);
Instead of having to tangle with the format of the following parameters (in fact, apply and call are only different in the format of the arguments), both apply and call are binding the Func's this to the first parameter, obj. Look at the following code:
1 function Foo () { 2 console.log (this .a); " 4 5 var obj = { 6 a:1 7 }; 9 var a = ' global ' ; 10 11 foo.call (obj); //
The This of Foo is bound to obj above.
The first parameter of apply and call can also be null, that is, not bound to any object, but it is actually bound to a global object:
1 function Foo () { this .a); 3 4 var obj = { 5 a:16 }; 7 var a = ' global ' ; 8 Foo.call (null ); // Strict mode is undefined, and non-strict mode is global
Although apply and call can bind this to the specified object, there is no problem with the callback function because both the apply and call are executed immediately at the moment, and the execution time of the callback function is indeterminate. And the context of the callback function is also indeterminate, and in the context of the callback function it may be difficult to get the this binding object we want.
To solve the problem of missing callback function bindings, we can use hard bind bind. Bind is useful for forcing an object to bind to this and cannot be modified after binding. This is useful for our event-driven programming model and can be used in a number of callback functions. In addition, bind in JS's functional programming is also a tool. Look at the following code:
1 functionfoo () {2Console.log ( This. a);3 }4 varObj1 = {5A:16 };7 varObj2 = {8A:29 };Ten varBar = Foo.bind (obj1);//Bar's This will always only point to obj1 OneBar ();//1 ABar.call (OBJ2);//1 because it cannot change the bind after bind, so it is still 1
4. New Binding
The new binding is the binding that is generated by invoking the function with the new operator. New in JS is different from other object-oriented programming languages. In general OOP, the new operator invokes the constructor of the class to generate a completely new class instance. There are no classes in JS and no constructors, and using the new operator to invoke a function actually does the following 4 things:
(1) Create a completely new object.
(2) The new object is connected to its prototype object.
(3) This new object is bound to this of the function call.
(4) If the function does not return a different object, the new expression will automatically return the newly-set object.
The code is as follows:
1 function Foo (a) {2 this. A = A; 3 }4varnew foo (1); 5 // 1
Summarize
This article describes the four cases of this, and it is necessary to emphasize that the binding of this is not seen where the function is defined, but where the function is called, or the context.
Deep parsing of the This keyword in javascript