Original address of the article


ES5 implements bind as follows

Function.prototype.bind = function(that){
        var self = this,
            args = arguments.length > 1 ? Array.slice(arguments.1) : null,
            F = function(){};

        var bound = function(){
            var context = that, length = arguments.length;
            if (this instanceof bound){
                F.prototype = self.prototype;
                context = new F;
            }
            varresult = (! args && ! length) ? self.call(context) : self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments);
            return context == that ? result : context;
        };
        return bound;
    }
Copy the code

Test 1

var bar = function() {
        console.log(this.x)
    }
var foo = {
  x: 3
}

var func = bar.bind(foo);
func(); / / 3
Copy the code

The bar function binds the x value in foo and prints 3

The main thing about bind is bound. What does bound do?

First, context stores that passed into the context, check this instanceof bound, when this instanceof bound == true? In test 1, this instanceof bound is false and this is Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window,… }, found to be the window object, because foo itself is in the window object.

So execute self.call(context) directly and return the result of execution 3, which is the result of our test 1.

When this instanceof bound == true, we need to use the empty function F to get the prototype of the main function.

The answer is instantiate, when do you instantiate?

Test 2

var bar = function() {
    console.log(this.x)
}
bar.prototype.name = function(){
  this.name = 'name';
}
var foo = {
  x: 3
}

var func = bar.bind(foo);
var newFunc = new func; // undefined
newFunc.name(); // name
Copy the code

Bar.bind (foo) is instantiated, so what does new do because it’s new? What’s going on in the new operator? Constructor == true this instanceof bound {constructor == true

So why does bar.bind(foo) pass foo with undefined instead of 3? Also because of the new operation, the current context is already the newly generated newFunc function. And when this instanceof bound == true, it assigns bar’s prototype to F, and bound returns newF, so bar’s prototype is assigned to newFunc.

If we look at the ES6 operation, the result is the same as in the above example.

var bar = function() {
    console.log(this.x)
}
bar.prototype.name = function(){
    console.log('name')}var foo = {
    x: 3
}
var func = bar.bind(foo);
func(); / / 3
/ / instantiate
var newFunc = new func; // undefined
    newFunc.name(); // name
Copy the code

Conclusion:

So what are the total number of things that bind does?

  • When there is no instantiation, the argument of the passed object is referred to the current function, the current function is executed, and the result is returned
  • Is used when instantiatingnewOperation generates a new function, the original functionprototypeAssign to a new function, execute a new function, and return a new function