In-depth understanding of the 4 binding rules of the first--this of this mechanism series

Source: Internet
Author: User

xTable of Contents [1] Default binding [2] implicit binding [3] implicit loss [4] explicit binding [5]new binding [6] strict mode before

If you want to ask which two knowledge points in JavaScript are easily confused, the scope query and this mechanism are definitely among the top ones. The previous scope series has described the scope knowledge in detail. This series begins with the introduction of another large mountain range--this mechanism for JavaScript. This article is the 4 binding rules for the first--this of the series

Default bindings

In the global environment, this is bound to window by default

Console.log ( this = = = window); // true

When the function is called independently, this is bound to the window by default

function foo () {    Console.log (this = = = //true

When the nested function is called independently, this is bound to the window by default

// Although the test () function is nested in the Obj.foo () function, the test () function is called independently, not a method call. So this is bound to windowvar a = 0 by default; var obj = {    2,    foo:function() {            function Test () {                Console.log (this. a);            }            Test ();}    } Obj.foo (); // 0

"Iife"

Iife immediately executes a function that is actually called directly after the function declaration executes

var a = 0; function foo () {    (function  Test () {        Console.log (this. a);    }) ()}; var obj = {    2,    Foo:foo}obj.foo (); // 0
// equivalent to the above example
var a = 0; var obj = {    a:2,    foo:function() {            function Test () {                Console.log ( This. a); } test (); }}obj.foo ();//0     

"Closures"

Similarly, the test () function is a standalone call, not a method call, so this is bound to window by default

[note] There are 4 ways to call the function, the function calls the relevant content to this point

var a = 0; function foo () {    function  Test () {        Console.log (this. a);    }     return test;}; var obj = {    2,    Foo:foo}obj.foo () (); // 0

Implicit binding

In general, when called by a function that is contained by a direct object, also called a method call, this is implicitly bound to the direct object

function foo () {    Console.log (this. a);}; var obj1 = {    A:1,    foo:foo,    obj2:{        A:2,        Foo:foo    }}  The direct object of the//Foo () function is obj1,this implicitly bound to Obj1Obj1.foo (); // 1 // the direct object of the Foo () function is that obj2,this is implicitly bound to Obj2Obj1.obj2.foo (); // 2

Implicit loss

Implicit loss means that a function that is implicitly bound loses the bound object, and thus binds to the window by default. The situation is error-prone but common.

"Function alias"

 var  a = 0;  function   Foo () {console.log ( this  .A);};  var  obj = {a:  2, Foo:foo}  //  The Obj.foo is given an alias bar, resulting in implicit loss, because only the Foo () function is assigned to bar, and bar is irrelevant to the Obj object  var  bar =< Span style= "color: #000000;" > Obj.foo;bar ();  // 0  
// equivalent to var a = 0; var function foo () {    Console.log (this. a);} Bar (); // 0

"Parameter Passing"

 var  a = 0;  function   Foo () {console.log ( this  .A);};  function   Bar (FN) {fn ();}  var  obj = {a:  2, Foo:foo}  //  When Obj.foo is passed as a parameter to the bar function, there is an implicit function assignment Fn=obj.foo. Similar to the example above, only the Foo function is assigned to FN, and the FN and obj objects have no relation to  bar (Obj.foo); // 0  
// equivalent to var a = 0; function Bar (FN) {    fn ();} Bar (function  foo () {    Console.log (this. a);});

"Built-in functions"

Built-in functions are similar to the previous example, and can also cause an implicit loss

var a = 0; function foo () {    Console.log (this. a);}; var obj = {    2,    foo:foo}settimeout (Obj.foo,+);   0
// equivalent to var a = 0; setTimeout (function  foo () {    Console.log (this . a);},100); // 0

Explicit binding

Binding an object to this by means of the call (), apply (), bind () method is called explicit binding. For the called function, it is called an indirect call.

var a = 0; function foo () {    Console.log (this. a);} var obj = {    A:2};foo (); // 0foo.call (obj); // 2

Normal explicit binding does not solve implicit loss problems

var a = 0; function foo () {    Console.log (this. a);} var obj1 = {    A:1}; var obj2 = {    A:2};foo.call (obj1); // 1foo.call (OBJ2); // 2

"Hard bind"

Hard binding is a variant of explicit binding, so this can no longer be modified

var a = 0; function foo () {    Console.log (this. a);} var obj = {    A:2}; var function () {    foo.call (obj);} // manually call Foo.call (obj) inside the bar function. Therefore, regardless of how the function bar is called later, it will always manually raise the Foobar () on obj; // 2setTimeout (bar,100); // 2bar.call (window); // 2

"API"

There are many new built-in functions in JavaScript with explicit binding capabilities, such as 5 iterative methods for arrays: Map (), ForEach (), filter (), some (), every ()

var id = ' window '; function foo (EL) {    console.log (el,this. id);} var obj = {    ' fn '};[ 1,2,3].foreach (foo); // 1 "Window" 2 "Window" 3 " window" [1,2,3].foreach (Foo,obj); // 1 "FN" 2 "FN" 3 "FN "

New binding

If a function or method call is preceded by the keyword new, it constitutes a constructor call. For this binding, called the new binding

The "1" constructor typically does not use the return keyword, which typically initializes the new object, which is explicitly returned when the function body of the constructor finishes executing. In this case, the result of the constructor call expression is the value of the new object

function fn () {    this. A = 2;}  var New fn (); Console.log (test); // {a:2}

"2" If the constructor uses a return statement but does not specify a return value, or returns a raw value, the return value is ignored and the new object is used as the result of the call

function fn () {    this. A = 2;      return ;} var New fn (); Console.log (test); // {a:2}

"3" If the constructor explicitly returns an object using the return statement, the value of the invocation expression is the object

var obj = {a:1}; function fn () {    this. A = 2;      return obj;} var New fn (); Console.log (test); // {a:1}

[note] Although sometimes the constructor looks like a method call, it will still use this new object as this. In other words, in the expression new O.M (), this is not an O

var o = {    function() {        returnthis;    }} var New  = = = O); // {} falseConsole.log (obj.constructor = = = O.M); // true

Strict mode

"1" in strict mode, the this point of the function that is called independently undefined

function fn () {    ' use strict ';    Console.log (this); // undefined }fn (); function fn () {    console.log (this);   window}fn ();

"2" in non-strict mode, when you use the call () or apply () method of a function, null or undefined values are converted to global objects. In strict mode, the this value of the function is always the specified value

 var  color = ' Red ' ;  function   Displaycolor () {console.log ( this  .color);} Displaycolor.call ( null ); // red  var  color = ' Red ' ;  function      Displaycolor () { ' use strict '  this  .color);} Displaycolor.call ( null ); // typeerror:cannot Read property ' color ' of NULL  

At last

The four binding rules for this are: default binding, implicit binding, explicit binding, and new binding, corresponding to the four invocation modes of the function: stand-alone invocation, method invocation, indirect call, and constructor call.

It is not difficult to distinguish these four kinds of binding rules, it is troublesome to develop eyes, to identify the situation of implicit loss

Ultimately, the reason JavaScript is so complicated is because the function is too powerful. Because the function is an object, the prototype chain is more complex, because the function can be passed as a value, so the execution of the environment stack is more complex;

Only understanding the function is understood by JavaScript

Above

In-depth understanding of the 4 binding rules of the first--this of this mechanism series

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.