On the skills of call, apply and bind_javascript in JavaScript

Source: Internet
Author: User
Tags event listener

In JavaScript, call, apply, and bind are the three methods of a function object, and the main effect of these three methods is to change the this point in the functions so that the ' move to the flower ' effect can be achieved. This article will explain the three methods in detail and list a few classic scenarios.

Call (Thisargs [, args ...])

The method can pass a Thisargs parameter and a list of arguments, Thisargs specifies the caller of the function at runtime, that is, the this object in the function, and the argument list is passed into the calling function. The value of Thisargs has the following 4 cases:

(1) Do not pass, or pass null,undefined, in the function of this point to the Window object

(2) passing the function name of another function, this point in the function refers to the function

(3) Pass the underlying type, such as a string, numeric, or Boolean type, in which the this point points to its corresponding wrapper object, such as String, number, Boolean

(4) Passing an object in the function that points to this object

function A () {
 console.log (this);//Output function A of this object
}
function B () {}///definition Functions b

var obj = {name: ' Onepixel '} ; Define Object obj

a.call ();//window
a.call (null);//window
a.call (undefined);//window
A.call (1);// Number
A.call (");//string
A.call (true);//boolean
A.call (b);//function B () {}
A.call (obj); Object

This is the core function of call, which allows you to invoke an object without a defined method, and this method can access the properties in that object, as to what is the benefit of doing so, as I'll say later, let's look at a simple example:

var a = {

 name: ' Onepixel ',//define A's property

 say:function () {///define Method
  Console.log ("Hi,i ' m function a!");
 }
;

function B (name) {
 Console.log ("Post params:" + name);
 Console.log ("I ' m" + this.name);
 This.say ();
}

B.call (A, ' test ');
>>
Post params:test
i ' m onepixel
i ' m function a!

When executing B.call, the string ' test ' is passed as a parameter to function B, and because of call, the this in function B points to object A, so it is equivalent to calling function B on object A, which actually does not have a definition of B.

Apply (thisargs[,args[]])

The only difference between apply and call is that the second argument is passed differently, and the second argument to apply must be an array, and call allows you to pass a list of arguments. What's worth noting is that although apply receives an array of arguments, but is passed to the calling function as a parameter list, let's look at a simple example:

Function B (x,y,z) {
 console.log (x,y,z);
}

B.apply (null,[1,2,3]); 1 2 3

This feature of apply is important and we will mention this feature in the following scenario.

Bind (Thisargs [, args ...])

Bind is a new method of ES5, which is similar to call, but has a significant difference from call/apply, that is, calls or apply automatically perform the corresponding function, and bind does not perform the corresponding function, except that it returns a reference to the function. In a cursory glance, bind seems to lag behind the call/apply, why ES5 to introduce bind?

In fact, the real purpose of ES5 's introduction of BIND is to make up for call/apply, because call/apply automatically executes on the target function, causing it to not be used in the event-binding function, because the event-binding function does not require us to execute it manually, It is automatically executed by JS inside when the event is triggered. Bind in the implementation of the change function this does not automatically execute the objective function, so you can solve the above problems perfectly, look at an example can understand:

var obj = {name: ' Onepixel '};

/**
 * Add click event Listener to document and bind the onclick function
 * Set OnClick's this as obj via the Bind method and pass the parameter
 p1,p2
* * Document.addeventlistener (' Click ', Onclick.bind (obj, ' p1 ', ' P2 '), false);

Triggers and executes
function OnClick (a,b) {
 console.log (
   this.name,//onepixel
   A,//p1
   b//p2 when clicking on the Web page)
 )
}

When clicked on the webpage, the onclick is triggered executes, the output onepixel p1 P2, explained this in the onclick is changed into the Obj object, in order to have a thorough understanding to bind, we looked at Bind's Polyfill realization:

if (! Function.prototype.bind) {
 Function.prototype.bind = Function (othis) {
  var Aargs = Array.prototype.slice.call (arguments, 1),
   Ftobind = This, where//this is pointing to the target function
   fbound = function () {return
    ftobind.apply (
     // If the external execution of var obj = new Fbound (), obj is used as the final this, discard the use of Othis
     this instanceof ftobind
       . This is the new obj
       : Othis | | This,//if the passed Othis is invalid, the caller of the Fbound is merged as this

     //The parameter passed through bind and the parameters passed by the call and passed as the final argument
     Aargs.concat ( Array.prototype.slice.call (arguments)));

  Copy the target function's prototype object into the new function, because the target function may be used as a constructor to use
  Fbound.prototype = This.prototype;

  Returns a reference to the Fbond, calling return Fbound on demand from outside;


Application Scenario One: inherited

As you know, there is no JavaScript in the Java, C # and other high-level languages in the Extend keyword, so JS does not inherit the concept, if you must inherit, call and apply can achieve this function:

function Animal (name,weight) {
 this.name = name;
 This.weight = weight;
}

function Cat () {
 Animal.call (this, ' cat ', ') ';
 Animal.apply (this,[' cat ', ' m '));

 This.say = function () {
  console.log ("I am" + this.name+ ", my weight is" + this.weight);
 }

var cat = new Cat ();
Cat.say ();//i am cat,my weight is 50

When cat is generated by the new operator, this in cat points to the Cat object, and the key to inheritance is that the Animal.call (this, ' cat ', ' 50 ') is executed in the cat, which is passed as a Thisargs parameter in call. So this in the animal method points to this in cat, and the this in cat points to the Cat object, so the this in animal points to the Cat object, and the name and weight properties are defined in animal. This is equivalent to defining these attributes in cat, so the Cat object has the attributes defined in animal to achieve the purpose of inheritance.

Application Scenario Two: Deceitful Act

Before we get to the bottom of this, let's take a look at a nonstandard jargon in javascript: Arraylike (class array/pseudo array)

The Arraylike object, which has a part of the array behavior, has already been shown in the DOM, and the rise of jquery makes Arraylike shine in JavaScript. The subtlety of the Arraylike object is that it is similar to the JS native array, but it is freely constructed and comes from the developer's extension of the JavaScript object, that is to say: for its prototype (prototype) We are free to define, But will not pollute to JS native array.

Arraylike objects are widely used in JS, such as the nodelist in the DOM, the arguments in the function are class array objects that store every element like an array, but it has no method of manipulating the array, and we can ' move ' some methods of the array by call ' To the Arraylike object, thus achieving the purpose of manipulating its elements. For example, we can traverse the arguments in a function like this:

function test () {
 //detects whether arguments is an instance of array
 console.log
   arguments instanceof array,//false
   Array.isarray (arguments)//false
 );
 Determine if arguments has a foreach method
 console.log (Arguments.foreach);//undefined

 //apply foreach in array to arguments
 Array.prototype.forEach.call (Arguments,function (item) {
  Console.log (item);//1 2 3 4
 });

}
Test (1,2,3,4);

In addition, for apply, we refer to its unique feature that the apply receives an array that is passed as a parameter list when passed to the calling function. This feature allows the apply to look more than call slightly, such as a scenario: given an array [1,3,4,7], and then the largest element in the array, and you know that there is no way to get the maximum value in the array, and in general you need to write code to implement it. And we know that there is a method in the Math object to get the maximum value, that is, Math.max (), the Max method needs to pass a list of arguments, and then returns the maximum value in those parameters. Instead of applying the Max method of the Math object to other objects, apply can also transform an array into a parameter list and pass it to Max to see the code at a glance:

var arr = [2,3,1,5,4];

Math.max.apply (Null,arr); 5

The above is call and apply more classic several application scenarios, master these skills, and apply these features to your actual project, will make your code look more interesting!

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.