Before we look at the call() and apply() principles, we need to understand what this does and how to use it. If you’re familiar with this, please read on.

Call method:

Syntax: call([thisObj[,arg1[, arg2[, [,.argn]]]]]) definition: to call a method of an object to replace the current object with another object. Note: The call method can be used to call a method instead of another object. The call method changes the object context of a function from its original context to the new object specified by thisObj. If no thisObj argument is provided, the Global object is used as thisObj.

The apply method:

Definition: Apply ([thisObj[,argArray]]) a method on an object that replaces the current object with another. Note: If argArray is not a valid array or arguments object, it will result in a TypeError. If neither argArray nor thisObj arguments are provided, the Global object will be used as thisObj and no arguments can be passed.

Call () and apply() work much the same, except that the parameter types are different to suit different usage scenarios. They’re all there to change the context in which a function is run, or, more bluntly, to change the direction of this inside a function.

For example

We have a classic saying that says, “Dragon born dragon, chicken born chicken, mouse born to make holes.” The genetic explanation is that certain animal behaviors may be regulated by a series of genes, but notice, we want the dragon to make holes. How can we do that? The following explains how call() and apply() work around this topic.

var dragon = {
	name : 'foo'
	// other attribute
}

var mouse = {
	name : 'tom'.makeHole : function(where){
		console.log(this.name + ' is making a hole in the ' + where)
	}
	// other attribute
}

mouse.makeHole.call(dragon,'hill')
Copy the code

Running the code above will print it on the console:

As you can see, we declared a Dragon object. We didn’t give it the ability to make holes, but we used call() to inherit the mouse method and do what the Mouse function does.

How does this work? Let’s look at the call() argument: The first one is an object that will replace the original this object in the Function class. We pass in this. Remember, this in the makeHole Function refers to the object that will instantiate this Function in the future (I know this is a mouthful). This refers to dragon. Except for the first argument, all subsequent arguments are passed to the parent function itself.

The apply() and call() functions are almost the same, except that the second argument to apply() can only be an array, which is passed as arguments to the argument list of the original function.

Simulate implementing the call() function

How does the call() function work? Let’s use an example to help us understand.

/ / create a Dragon
function Dragon(name) {
  this.name = name;
}

// Create a talking function
function say(content) {
  console.log(this.name + ':' + content)
}

// Emulate the native call function
Function.prototype.myCall = function(context) {
  context = context || window;
  
  var args = [];
  context.fn = this;

  for (var i = 1; i < arguments.length; i++) {
    args.push(arguments[i]); }; context.fn(... args);delete context.fn;
};

// instantiate a dragon named 'foo'
var foo = new Dragon('foo')

// let foo speak
say.myCall(foo, 'I can talk! ')
Copy the code

The code above is easy to understand, the only difficulty is to understand the myCall function on the prototype chain. Let’s analyze the implementation steps:

  1. Do a multi-scene adaptation whenmyCallWhen the function receives no arguments,contextThe corresponding iswindowobject
  2. Creates an empty array to receive the parameters.
  3. The bindingthisHere,thisIt’s in contextsayFunction.
  4. forLoop to add parameters toargsArray, the loop starts at 1 because bit 0 isfooObject, not the argument we need
  5. Executes the function and willargsThe array is passed in as the rest parameter. Here is the ES6 notationRest parametersThe document
  6. Delete function

The printed result is:

As you can see, here we’ve implemented making a dragon named Foo speak! The apply() function is implemented similarly, and you can modify the above example implementation, primarily in the parameters section.