Detailed Explanation of call apply and bind Methods of JavaScript Function
- 2021-11-13 06:21:59
- OfStack
Summarize
1. Similarities
Can change the direction of the internal this when the target function is executed The first parameter of the method is used to specify the internal this value when the function is executed Supports passing arbitrary parameters to the objective function If undefined and null are not passed to the first parameter of the method, this in the target function points to window object in JavaScript normal mode, and undefined and null in strict mode respectively.2. Differences
The apply () method can take two parameters, while the call () and bind () methods can take multiple parameters. The apply () method passes arguments to the target function only by using an array of arguments or an arguments object as the second argument of the method, while the call () and bind () methods enumerate the arguments one by one after the first argument of the method. When the call () and apply () methods are called, the target function is executed immediately, whereas the bind () method does not. It returns a new function-a copy of the target function, the this inside which points to the first parameter of the bind () method, and then executing the new function is equivalent to executing the target function. Only the bind () method implements the Curritization of the function, so the parameters can be passed to the objective function twice.call () method
Calling the call () method immediately executes the target function, changing the direction of the this inside the function. The this point is determined by the first parameter of the method, and any parameter enumerated one by one later is passed as parameter 11 of the objective function. For the last point of the same point in the beginning summary, an example is as follows:
/* Normal mode */
let obj = {
sum(a, b) {
console.log(this)
return a + b
}
}
// Execute sum Functional apply , bind Method, printed this Same as below
obj.sum.call() // Print window
obj.sum.call(undefined, 1, 2) // Print window
obj.sum.call(null, 1, 2) // Print window
/* Strict model */
'use strict'
// Execute sum Functional apply , bind Method, printed this Same as below
obj.sum.call() // Print undefined
obj.sum.call(undefined, 1, 2) // Print undefined
obj.sum.call(null, 1, 2) // Print null
Analog implementation
1. Key points
The myCall () method is added to the Function prototype object, and when the target function calls the method, the this inside the myCall () method points to the target function. The target function is executed as a method of the context object, whereby the this inside the target function points to the context object. . Delete the target function from the context object Use the extension operator... to process arguments passed into the target function2. In the simulation implementation of call (), apply () and bind (), when the first parameter is not passed or undefined and null are passed, the this in the normal mode and strict mode of JS is treated in a unified way, that is, this in the objective function points to window objects.
3. The code is as follows
Function.prototype.myCall = function (context, ...args) {
if (context === undefined || context === null) {
context = window
}
// The following behavior core code
context.fn = this
const result = context.fn(...args)
delete context.fn
return result
}
let obj1 = {
basicNum: 1,
sum(a, b) {
console.log(this)
return this.basicNum + a + b
}
}
let obj2 = {
basicNum: 9
}
console.log(obj1.sum.call(obj2, 2, 3)) // 14
console.log(obj1.sum.myCall(obj2, 2, 3)) // 14
apply () method
Calling the apply () method immediately executes the target function, changing the direction of the this inside the function. The this point is determined by the first parameter of the method, and the second parameter is an array of parameters or an arguments object, and the parameters represented by each array element or an arguments object are passed in correspondingly as parameter 11 of the target function.
Analog implementation
1. Key points
The myApply () method is added to the Function prototype object, and when the target function calls the method, the this inside the myApply () method points to the target function. The target function is executed as a method of the context object, whereby the this inside the target function points to the context object. Delete the target function from the context object Use the extension operator... to process arguments passed into the target function2. The code is as follows
Function.prototype.myApply = function (context, args) {
if (context === undefined || context === null) {
context = window
}
// The following behavior core code
context.fn = this
const result = context.fn(...args)
delete context.fn
return result
}
console.log(obj1.sum.apply(obj2, [2, 3])) // 14
console.log(obj1.sum.myApply(obj2, [2, 3])) // 14
bind () method
Calling the bind () method will return a new function-a copy of the target function. The this inside the function points to the first parameter of the method, and any parameters listed one by one will be passed in as parameter 11 of the target function. After that, executing the new function is equivalent to executing the target function. The bind () method implements the Curritization of the function, so the parameters can be passed to the objective function in two times, the first time the parameters are enumerated after the first parameter of the bind () method, and the second time the parameters are enumerated in the new function.Analog implementation
1. Key points
The myBind () method is added to the Function prototype object, and when the target function calls the method, the this inside the myBind () method points to the target function. The target function is executed as a method of the context object, whereby the this inside the target function will point to the context object. Delete the target function from the context object Use the extension operator... to process the initial parameters and subsequent parameters passed into the target function.2. The code is as follows
Function.prototype.myBind = function (context, ...initArgs) {
if (context === undefined || context === null) {
context = window
}
// Cache this Value
const _this = this
return function (...args) {
// The following behavior core code
context.fn = _this
const result = context.fn(...initArgs, ...args)
delete context.fn
return result
}
}
console.log(obj1.sum.bind(obj2, 2)(3)) // 14
console.log(obj1.sum.myBind(obj2, 2)(3)) // 14
Related knowledge points
On the Direction of this in JavaScript