A, the title

  • Bind (context, 1, 2)(3, 4) is equivalent to call(context, 1, 2, 3, 4)

In front end interviews, one often asks the difference between call, apply, and bind.

  • call: fn.call(context, 1, 2, 3, 4)
  • apply: fn.apply(context, [1, 2, 3, 4])
  • bind: fn.bind(context, 1, 2)(3, 4)

Context refers to this, and the results of the above three methods are the same. The difference between call and apply is that the parameters are passed in different ways, while bind returns an unexecuted method, which can continue to pass in parameters during execution. This implements currization of functions and improves the reuse of parameters

Second, the implementation process

Function.prototype.myBind = function (context = window) { // Add the mybind method to the prototype
   // var args = array. from(es6) console.log(args instanceof Array)
   var argumentsArr = Array.prototype.slice.call(arguments) // Class array to array
   var args = argumentsArr.slice(1) // The following parameters
   var self = this // Call the method itself
   return function () { // Return a method to be executed
       var newArgs = Array.prototype.slice.call(arguments) // Return arguments to function, class array to array or use ES6 destruct assignment
       self.apply(context, args.concat(newArgs)) // Merge two arGs}}Copy the code

3. Test results

/ / test
var name = 'window name'
var obj = {
    name: 'obj name',}var fn = function () {
    console.log(this.name, [...arguments])
}
fn(1.2.3.4) // This points to the window
fn.myBind(obj, 1.2) (3.4) // mybind changes this to point
fn.bind(obj, 1.2) (3.4) / / native bind

// The above results are as follows:
// window name [1, 2, 3, 4]
// obj name [1, 2, 3, 4]
// obj name [1, 2, 3, 4]
Copy the code

Make sure this points to and the prototype chain is attached when using the new function

Function.prototype.MyBind = function(context){
    var self = this
    var args = Array.prototype.slice.call(arguments.1)
    var temp = function () {}
    var fn = function () {
        var newArgs = Array.prototype.slice.call(arguments)
        // This should be an instance of fn if called by new
        return self.apply(this instanceof fn ? this : (context || window), args.concat(newArgs) )
    }
    // Maintain the fn prototype
    temp.prototype = self.prototype
    fn.prototype = new temp()
    return fn
}
Copy the code