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 immediatelycall/apply
  • Can be used if there are not many parameters to passfn.call(thisObj, arg1, arg2 ...)
  • If you have a lot of arguments to pass, you can use an array to organize the argumentsfn.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 timeconst newFn = fn.bind(thisObj); newFn(arg1, arg2...)

Realize the principle of

  • callThe 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
  • applyThe 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
  • bindThe 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