Deep understanding of this, call, bind, apply

Source: Internet
Author: User

First of all, look at one of NetEase's interview questions:

varA ={A:"haha", Geta:function () {Console.log ( This. a); }    }varb ={A:"Hello"    }varGeta =A.geta;varGetA2 =Geta.bind (a); function run (FN) {fn ();}//Output separatelyA.geta ();//hahaGeta ();//the A object under WindowRun (A.geta);//the A object under WindowGeta2.call (b);//haha

  Three points are examined here: the understanding of formal parameter arguments, the direction of this, and the effect of call and bind on this point.

One, this point problem

  About this point, previous article: understanding JavaScript this keyword has a better summary.

(1)   Here are three simple things to do:

1, if this in the function does not call its object, then this point is the window ( Note: This case in strict mode is empty, that is, undefined)

2. If this is called by an object that does not contain child objects, this refers to the object that called it.

3. If this in the function is called by an object containing a multilevel object, this point is only the object of its upper level, as in the following example:

var demoobj = {    A:1,    b:{        fun:function () {            Console.log (this  . a);}}    Demoobj.b.fun (); // undefined because this is pointing to demoobj.b,b there's no a

 This does not point to the Demoobj object, but to the Demoobj.b object, where a is not found in the Demoobj.b object, so the undefined is output.

  (2) There are three special cases:

1, or the above example, change a downward use of the function of the way, as follows.

var demoobj = {    A:1,    b:{        fun:function () {            Console.log (this  . a);     }} var newfun = demoobj.b.fun;newfun (); // undefined,this point to Window

Here still get undefined, but this point is window, here is undefined because not found in the Window object in a, only output undefined. Although the function fun is called by Object B, it is not executed when the fun is assigned to the variable Newfun, Newfun's parent object window, so the final execution point is the window.

2. The effect of the constructor with the new instance object on this.

function Fun () {    this"haha";} var New  //haha

Here the object stu.name can output Haha, because the new keyword is to create an object instance, the Stu object contains this.name This property, the equivalent of replication but not executed . Calling this function at execution time is the object Stu, so this is pointing to the object Stu.

  What happens when you create an object with the new operator:

  The first step is to create an instance of Object objects.
The second step is to assign the scope of the constructor to the new object (so this will point to the new object).
Step three: Execute the code in the constructor (the execution here does not really point to where this is, but instead adds a property to the new object).
Fourth step: Return the newly generated object instance

The original constructor is a method of the Window object, and if called directly without the new operator, the constructor's execution object is window, that is, this points to window. Now with the new operator, this will point to the newly generated object. Understanding this step is crucial.

3, the function of return has the effect on the this when new (the normal constructor is no return statement), we first look at the following several examples.

 //  function fun () { this . Name = "  haha   " ;   return   {};  var  stu = new   fun (); Console.log (Stu.name);  // undefined,stu to {}   
 //  function fun () { this . Name = "  haha   " ;  return   function () {};}  var  stu = new    fun (); Console.log (Stu.name);  // undefined   
 //  function fun () { this . Name = "  haha   " ;  return  123  ;}  var  stu = new    fun (); Console.log (Stu.name);  // haha,stu as a fun instance   
// Example 4 function Fun ()  {      this'haha';       return undefined;} var New Fun ();   // haha

You can see that if the return is an object, this will point to the returned object, and if return is not an object, then this is an instance of the function.

But the return is null when it is more special. Although NULL is also an object, this is also a pointer to an instance of a function.

// Example 5 function Fun ()  {      this'haha';       return NULL ;} var New Fun ();   // haha

Effect of call, bind and apply on this direction

  Call and apply have only a different parameter, so this is just about call, because the call and bind parameters are used the same way.

  1, call is the dynamic change of this point, that is, the method of changing objects to perform the original object method, and immediately execute;

2, bind is static change this point, and return a modified function.

Take the beginning of the topic the last output to say:

If you use call only: When executing to these two sentences, the direction of this is changed dynamically, so the output of call (b) Hello,call (a) is haha.

Geta.call (b); // Hellogeta.call (a); // haha

Next look at the effect of bind:

var getA2 = Geta.bind (a);

Here Geta is actually A.geta, then Geta.bind (a) will this point a, in fact, or return the A.geta function assigned to getA2. Note: The function has not changed, but the internal has pointed to a.

Geta2.call (b); // haha // equivalent to A.geta.call (b);

At this point, either a or B in call will output hello because the internal this has been bound to B by bind.

In general, thecall method is to change this at the time of invocation and execute the function immediately, and the bind method can change the this in the function before the corresponding function can be called when needed.

Third, call, bind, apply usage:

1, fun.apply (Context,[argsarray])

Call the fun now and point the fun function's original this to the incoming new context object, implementing the same method for reuse on different objects .

Context: The incoming object, replacing the fun function original this;

Argsarray: An array or class array object in which the array parameters are expanded as separate arguments to the fun function, requiring attention to the order of the parameters.

2. Fun.call (context,[arg1],[arg2],[...])

With apply, except that the parameter list is different, the call parameter needs to be passed in separately. If you do not know the number of arguments, apply is used.

Use:

Math.max ()//only receive individual parameters, you can use the Max method above the array by using the following method:Math.max.apply (NULL, array);//The array array parameter is expanded into a separate parameter and then passed inArray.prototype.push.apply (ARR1,ARR2);//take an array and push it into another array; instead of apply, the subsequent array parameters are push in as an element. Array.prototype.slice.call (arguments);//using the slice method on a voxel group objectfunction IsArray (obj) {returnObject.prototype.toString.call (obj) = = ='[Object Array]' ;} //verifies whether the array

3. Fun.bind (context,[arg1],[arg2],[...])

The context in which the fun method executes will never change. Statically Specify this

Arg1: The argument list to pass to the new function

Returns a function for subsequent calls whose function body is the same as the original function fun, but the new function's this points to the newly passed-in context object. The new function will have the initial parameters specified by the Bind method arg1/arg2 ..., and the arguments for subsequent calls to the new function are lined up after the existing parameters.

Use:

//The original function has 4 parametersvarDisplayargs =function (Val1, Val2, Val3, Val4) {Console.log (Val1+" "+ Val2 +" "+ Val3 +" "+val4);}varEmptyobject = {};//when a new function is generated, the Bind method specifies 2 parameters, and the new function takes the two argumentsvarDISPLAYARGS2 = Displayargs.bind (Emptyobject, A,"a");//call to pass in another 2 arguments, after the 2 arguments passed in the Bind methodDISPLAYARGS2 ("b","C");//Output:12 a b c

Bind parameters can be added again at execution time, but note that the parameters need to be added in the order of the formal parameter

var demoobj = {    name:"haha",    fun:function (a,b,c) {        Console.log (a,b,c);    }} var newfun = demoobj.fun; var newFun2 = Newfun.bind (Demoobj,5); newFun2 (7,9); // 5,7,9

Deep understanding of this, call, bind, apply

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.