What are the uses of ‘call’, ‘apply’ and ‘bind’

Call, apply

The call() method calls a function with a specified this value and one or more arguments given separately. Note: The syntax and actions of this method are similar to those of apply(), except that call() accepts a list of arguments, while apply() accepts an array of arguments.

function obj1() {}

obj1.prototype = {
	name: "hhh".sayHi: function() {
		console.log("My name is " + this.name); }}let obj2 = new obj1;
boj2.sayHi();	// My name is hhh

obj3 = {
	name: "ks"
}
obj2.sayHi.call(obj3);		// My name is ks
obj2.sayHi.apply(obj3);	// My name is ks
Copy the code

The main advantage of using Apply and call is that the object does not need to have any coupling with the method. You can use xxx.sayhi.call (XXX) to manually pass XXX into the function as this.

Call, apply

Note that apply passes an array of arguments, while call passes arguments in order

let age1 = function(iterm1, iterm2) {
  return iterm1 + iterm2
};
age1.call(this, iterm1, iterm2); 
age1.apply(this, [iterm1, iterm2])
Copy the code
  1. The object that calls call and apply must be a Function.

  2. The first argument to call is passed this(automatically converted to an object). If not, the default is the global object Window.

  3. Starting with the second parameter, any parameter can be accepted. Each parameter is mapped to the Function parameter at the corresponding location. But if you pass all the parameters as an array, they are mapped as a whole to the first parameter corresponding to Function, after which the parameters are empty.

  4. Apply accepts only two arguments, the first of which has the same rules as Call.

  5. The second argument, which must be an array or class array, will be converted to a pseudo-array, passed into Function, and mapped to the corresponding argument of Function. This is an important distinction between call and apply.

What is a pseudo-array?

Arrays can be called with corner markers, such as array[0]; Has the length attribute length; Archetypes with arrays (push, toString…) Can be traversed by a for loop or forEach method.

let array1 = {
    0: 1,
    1: 2,
    2: 3,
    length: 3
};
Copy the code
  • Array1 can be called with a corner marker, with the length property, and traversed through a for loop.
  • A pseudo-array cannot use methods on the array prototype chain like forEach, splice, and push (because it has no array prototype) and can passArray.form(fn) turns anything that is not an Array into an Array.

Examples of apply and call usage

  • Interarray append
var array1 = [12 , "foo" , {name "Joe"}, -2458];  
var array2 = ["Doe" , 555 , 100];  
Array.prototype.push.apply(array1, array2);  
/* Array1 values [12, "foo", {name "Joe"}, -2458, "Doe", 555, 100] */
Copy the code
  • Gets the maximum and minimum values in the array
var  numbers = [5.458 , 120 , -215 ];  
var maxInNumbers = Math.max.apply(Math, numbers),	/ / 458
	maxInNumbers = Math.max.call(Math.5.458 , 120 , -215);	/ / 458
Copy the code
  • Verify array (provided the toString() method has not been overridden)
functionisArray(obj){  
    returnObject.prototype.toString.call(obj) === '[object Array]' ;
}
Copy the code

Class (pseudo) arrays use array methods

var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
Copy the code

The interview questions

// Use the log agent console.log
function log(msg){
  console.log(msg);
}

log(1);
log(1.2);

// The elegant way
function log(){
  console.log.apply(console.arguments);
};

log(1);
log(1.2);

// Add a (app) prefix
function log(){
  var args = Array.prototype.slice.call(arguments);
  args.unshift('(app)');

  console.log.apply(console, args);
};

Copy the code

bind

  • The bind() method creates a new function, and when bind() is called, this of the new function is specified as the first argument to bind(), and the remaining arguments will be used as arguments to the new function.
  • Use.bind to keep this unchanged
  function f1(p1, p2) {
    console.log(this. p1. p2)
  }
  let f2 = f1.bind({name: 'hhh'}) // f2 is the function where f1 binds this
  f2() Call (name: 'HHH ')
Copy the code
  • .bind can also bind other parameters
  let f3 = f1.bind({name:'hhh'}, 'hi')
  f3() Call ({name: 'HHH '}, hi)
Copy the code

Call, apply, bind

let obj = {
	x: 99};let foo = {
	getX: function() {
		return this.x; }}console.log(foo.getX.bind(obj)());		/ / 99
console.log(foo.getX.call(obj));		/ / 99
console.log(foo.getX.apply(obj));		/ / 99
Copy the code

reference

  • Github.com/chokcoco/ap…
  • Segmentfault.com/a/119000001…
  • mdn