Similarities and differences between the three
Similarities:
All three are used to change the context of the function, which is referred to by this.
Difference:
Fn. bind: does not call immediately, but returns a new function that has been bound.
Fn. call: call immediately, return the result of function execution, this refers to the first argument, can be followed by multiple arguments, and these are the arguments of the fn function.
Fn. apply: call immediately, return the result of the function execution, this refers to the first argument, the second argument is an array, the contents of the fn function parameters.
Application scenarios
- Needs to be invoked immediately
call
/apply
- Can be used if there are not many parameters to pass
fn.call(thisObj, arg1, arg2 ...)
- If you have a lot of arguments to pass, you can use an array to organize the arguments
fn.apply(thisObj, [arg1, arg2 ...] )
- Instead of executing it immediately, you want to generate a new function and bind it to an object for a long time
const newFn = fn.bind(thisObj); newFn(arg1, arg2...)
Realize the principle of
call
The implementation of the
Function.prototype.myCall = function(thisObj = window){thisobj. fn = this // this refers to the myCallfunction/ / handle the argumentslet arg = [...arguments].slice(1)
letresult = thisObj.fn(... Arg) // Execute the function delete thisobj.fnreturn result
}
Copy the code
verify
var foo = {
value: 1
};
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
bar.myCall(foo, 'kevin', 18);
// kevin
// 18
// 1
Copy the code
apply
The call implementation is similar to that of Call
Function.prototype.myApply = function (context = window, arr){
context.fn = this
let result
if(! arr){ result = context.fn() }else{ result = context.fn(... arr) } delete context.fnreturn result
}
Copy the code
bind
The implementation of the
Bind is implemented with the help of apply
Function.prototype.myBind = function(context){// Type judgmentif(typeof this ! = ='function'){
throw new TypeError('must be a function')}letSelf = this // this is calledbindThe function oflet argsArr = [...arguments].slice(1)
return function() {let bindFuncArg = [...arguments] // Merge arguments passed twicelet totalArgs = argsArr.concat(bindFuncArg)
return self.apply(context, totalArgs)
}
}
Copy the code