javascript call apply and bind methods

  • 2021-01-25 07:01:56
  • OfStack

In JavaScript, call, apply, and bind are the three methods that come with Function objects, and this article will use several scenarios to understand the three methods in detail.

call()

The call() method calls a function or method with one specified this value and several specified parameter values.

When a function is called, one different this object can be assigned. this refers to the current object, the first argument of the call method.

Through call method, you can borrow the other one on one object on the object methods, such as Object. prototype. toString. call ([]), is a borrowed Object Array object on the object method.

fun.call(thisArg[, arg1[, arg2[,...]])
thisArg
The this value specified when the fun function is run. You need to pay attention to the following cases

null (this, undefined, this, window, null
(2) Passing the name of another function. The value of this in this function is not necessarily the true value of this when this function is executed
(3) this with a primitive value (number, string, Boolean) will point to the autowrapped object of the primitive value, such as String, Number, Boolean
(4) Pass 1 object. this in the function points to this object

arg1, arg2, ...
The list of parameters specified.

example
Primary application examples


function a(){
 // Output function a In the this object 
 console.log(this); 
}
// Define a function b
function b(){} 

var obj = {name:' This is a 1 A � silk '}; // Define the 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

ES67en uses the ES66en method to call an anonymous function and specify the context

In the following example, when the greet method is called, the method's this value is bound to the i object.


function greet() {
 var reply = [this.person, ' is 1 A lightweight ', this.role].join(' ');
 console.log(reply);
}

var i = {function greet() {
 var reply = [this.person, ' is 1 A lightweight ', this.role].join(' ');
 console.log(reply);
}

var i = {
 person: 'JSLite.io', role: 'Javascript  Library. '
};

greet.call(i); 
// JSLite.io  is 1 A lightweight  Javascript  Library. 


 person: 'JSLite.io', role: 'Javascript  Library. '
};

greet.call(i); 
// JSLite.io  is 1 A lightweight  Javascript  Library. 

Call anonymous functions using the call method

In the following example, we create an anonymous function inside the for loop, and then execute that anonymous function with each array element as the specified this value by calling the function's call method. The main purpose of this anonymous function is to add an print method to each array element object. The print method prints out the correct index number of each element in the array. Of course, we don't have to pass the array elements to the anonymous function as this values (normal arguments will do), just to demonstrate the use of call.


var animals = [
 {species: 'Lion', name: 'King'},
 {species: 'Whale', name: 'Fail'}
];

for (var i = 0; i < animals.length; i++) {
 (function (i) { 
 this.print = function () { 
 console.log('#' + i + ' ' + this.species + ': ' + this.name); 
 } 
 this.print();
 }).call(animals[i], i);
}
//#0 Lion: King
//#1 Whale: Fail

Use the call method to call the function to pass arguments


var a = {
 name:'JSLite.io', // define a The properties of the 
 say:function(){ // define a The method of 
 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!

apply()

The syntax is almost identical to that of the call() method, except that the second argument of apply must be an array (or an arraylike object) with multiple arguments. This feature of apply is important,

When you call an existing function, you can specify an this object for it. this refers to the current object, that is, the object that is calling the function. With apply, you can write the method once and then inherit it in another object, instead of writing the method repeatedly in a new object.

Syntax: fun.apply(thisArg[, argsArray])
Note: Note: Chrome 14 and Internet Explorer 9 still do not accept class array objects. If you pass in class array objects, they throw an exception.

parameter
thisArg

thisArg parameters of call as above.

argsArray

An array or array-like object whose elements are passed as individual arguments to the fun function. If the value of this parameter is null or undefined, then no parameters are passed in. As of ECMAScript 5, class array objects can be used.

example


function jsy(x,y,z){
 console.log(x,y,z);
}

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

Examples of using apply to link constructors

You can use apply to link an object to a constructor, similar to Java. In the following example we will create a global Function function called construct, which enables you to use an array-like object in the constructor instead of a parameter list.


Function.prototype.construct = function(aArgs) {
 var fConstructor = this, 
 fNewConstr = function() { 
 fConstructor.apply(this, aArgs); 
 };
 fNewConstr.prototype = fConstructor.prototype;
 return new fNewConstr();
};
function MyConstructor () {
 for (var nProp = 0; nProp < arguments.length; nProp++) {
 console.log(arguments,this)
 this["property" + nProp] = arguments[nProp];
 }
}
var myArray = [4, "Hello world!", false];
var myInstance = MyConstructor.construct(myArray);

console.log(myInstance.property1);  // logs "Hello world!"
console.log(myInstance instanceof MyConstructor); // logs "true"
console.log(myInstance.constructor);  // logs "MyConstructor"

Use apply and built-in functions

The clever use of apply allows you to use built-in functions for tasks that would otherwise need to be written to iterate over arrays of variables. In next example we will use Math. max/Math min to find out the maximum/minimum value in an array.


// It has the largest and smallest numeric values in it 1 Array objects 
var numbers = [5, 6, 2, 3, 7];

/*  use  Math.min/Math.max  in  apply  The application of  */
var max = Math.max.apply(null, numbers);
// 1 In most cases, it is  Math.max(5, 6, ..)  or  Math.max(numbers[0], ...)  To find the maximum 
var min = Math.min.apply(null, numbers);

// This is what we usually do to find the maximum or minimum of a number 
// Compare chestnuts on the top, does the bottom look less comfortable than the top? 
max = -Infinity, min = +Infinity;
for (var i = 0; i < numbers.length; i++) {
 if (numbers[i] > max)
 max = numbers[i];
 if (numbers[i] < min) 
 min = numbers[i];
}

The parameter array is chunked and looped in


function minOfArray(arr) {
 var min = Infinity;
 var QUANTUM = 32768;

 for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
 var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
 console.log(submin, min)
 min = Math.min(submin, min);
 }

 return min;
}

var min = minOfArray([5, 6, 2, 3, 7]);


bind

The bind() function creates a new function (called the binding function)

bind is a method added to ES5
Passing parameters is similar to call or apply
The corresponding function is not executed; call or apply automatically executes the corresponding function
Returns a reference to the function
fun.bind(thisArg[, arg1[, arg2[,...]])

The following example: when the click on the web, EventClick is triggered, the output JSLite. io p1 p2, showed that the this EventClick bind change into obj object. If you change EventClick.bind(obj,'p1','p2') to EventClick.call(obj,'p1','p2'), the page will output JSLite.io p1 p2


var obj = {name:'JSLite.io'};
/**
 *  to document add click Event listener, and bind EventClick function 
 *  through bind Methods set up EventClick the this for obj , and pass the parameters p1,p2
 */
document.addEventListener('click',EventClick.bind(obj,'p1','p2'),false);
// Triggered and executed when a web page is clicked 
function EventClick(a,b){
 console.log(
  this.name, //JSLite.io
  a, //p1
  b //p2
 )
}
// JSLite.io p1 p2

Compatible with


if (!Function.prototype.bind) {
 Function.prototype.bind = function (oThis) {
 if (typeof this !== "function") {
 // closest thing possible to the ECMAScript 5
 // internal IsCallable function
 throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
 }

 var aArgs = Array.prototype.slice.call(arguments, 1), 
 fToBind = this, // this In this case, I'm referring to the target function 
 fNOP = function () {},
 fBound = function () {
  return fToBind.apply(this instanceof fNOP
   ? this // At this time this is new Out of the obj
   : oThis || this,// If the passed oThis Invalid, will be fBound As the caller of this
  
  // Will be sent to you by bind The passed argument is merged with the argument passed at the time of the call and passed as the final argument 
  aArgs.concat(Array.prototype.slice.call(arguments)));
 };
 fNOP.prototype = this.prototype;
 // Copy the prototype object of the target function into the new function, since the target function may be used as a constructor 
 fBound.prototype = new fNOP();
 // return fBond Is invoked externally on demand 
 return fBound;
 };
}

Compatible with examples from: https: / / developer mozilla. org/zh - CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind # Compatibility

Application scenarios: Inheritance


function greet() {
 var reply = [this.person, ' is 1 A lightweight ', this.role].join(' ');
 console.log(reply);
}

var i = {function greet() {
 var reply = [this.person, ' is 1 A lightweight ', this.role].join(' ');
 console.log(reply);
}

var i = {
 person: 'JSLite.io', role: 'Javascript  Library. '
};

greet.call(i); 
// JSLite.io  is 1 A lightweight  Javascript  Library. 


 person: 'JSLite.io', role: 'Javascript  Library. '
};

greet.call(i); 
// JSLite.io  is 1 A lightweight  Javascript  Library. 

0

Prototype extension

Extend and customize methods on prototype functions without contaminating native functions. For example, we extend forEach by 1 forEach on Array


function greet() {
 var reply = [this.person, ' is 1 A lightweight ', this.role].join(' ');
 console.log(reply);
}

var i = {function greet() {
 var reply = [this.person, ' is 1 A lightweight ', this.role].join(' ');
 console.log(reply);
}

var i = {
 person: 'JSLite.io', role: 'Javascript  Library. '
};

greet.call(i); 
// JSLite.io  is 1 A lightweight  Javascript  Library. 


 person: 'JSLite.io', role: 'Javascript  Library. '
};

greet.call(i); 
// JSLite.io  is 1 A lightweight  Javascript  Library. 

1


Related articles: