[JS Footprints] Revisit Bid

Keywords: Javascript

concept

The bind() method returns a new function (called a binding function), which has the same function body as the original function (using the function of bind(), but the binding function has new this values and parameters.

To put it bluntly, bind() is to create a function with new this and arguments.

Grammar:

funName.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg

The direction of this in the binding function. It can be null, undefined, {}, or any other object. It could be another function.

This parameter cannot be overridden.

arg1, arg2, ...

Optional.

The parameters passed to the binding function.

Pass it as the default argument to the binding function.

Assuming that the parameter is a list, there are now two kinds of parameters, one is the parameter of bind, and the other is the parameter passed in a new binding function. The parameter of bind() precedes the parameter of the binding function.

Usage: You can make the binding function have an initial default parameter.

Example:

function funa(){
    "use strict";
    console.log(arguments[0]);//33
    console.log(arguments[1]);//11
    
}
var o = {
    x:1
}
var funb = funa.bind(o,33);
funb(11);//Output 33n 11

Compatibility:

The browsers that support the bind() method are IE9+.

The Difference between Bid and call and apply

Bid is a new method in ES5. It does not execute the corresponding function (call or application automatically executes the corresponding function), but returns a reference to the bind ing function.

  • The difference between call and apply is that the way to accept parameters is different.
  • bind: Not immediately. And apply and call are executed immediately.

bind and constructor

The constructor can use bind(), and then create an instance again.

The values of this provided by bind() are ignored, and the parameters provided are still prefixed to the constructor call.

function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype.toString = function () {
    return this.x + ',' + this.y;
};

var p = new Point(1, 2);
p.toString(); // '1,2'

var YA = Point.bind(null, 0);

var axis = new YA(5);
axis.toString(); // '0,5'

axis instanceof Point; // true
axis instanceof YA; // true
new Point(17, 42) instanceof YA; // true

Example:

window.color = "red";
var o = { color: "blue" };

function sayColor() {
    console.log(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue

bind() application

this is the method of changing objects

Aim: To make the method of an object not be used by the object, the direction of this is still the object.

Reason: Create a variable, point to the method as the object, and get a new function. This value in this new function no longer points to the original object.

name = "hello";

var mo = {
    name:2010,
    getName:function(){
        console.log(this.moyu);
        
    }
};

mo.getName();//2010

var newMo = mo.getName;//In this case, "this" points to the global scope window.


newMo();//hello

var nextMo = mo.getName.bind(mo);
nextMo();//2010

Setting default arguments

bind() can point undefined as this, and then pass in the default argument.

Usage:

fun.bind(undefined,33);

function list(){
   let res = Array.prototype.slice.call(arguments);
    console.log(res);
    
}

list(1,2,3);//[1,2,3]

let newList = list.bind(null,3);
newList();//[3]
newList(1);//[2,1]

Cooperate with setTimeout

By default, using setTimeout(function,time); the function's this keyword points to window.

In the prototype approach, this is the instance object. With setTimeout, the instance object must be explicitly bound to its function, otherwise this is a window object.

function LateBloomer() {
    this.petalCount = Math.ceil(Math.random() * 12) + 1;
}


LateBloomer.prototype.declare = function() {
    console.log('I am a beautiful flower with ' +  this.petalCount + ' petals!');
};

LateBloomer.prototype.bloom = function() {
    console.log(this);//LateBloomer {patalCount:4};
    
    setTimeout(this.declare.bind(this), 1000);
    //Zxy456: Both this points to LateBloomer.
    //If bind is not added, this of the function called by setTimeout is window. This in declare becomes window.
};


var flower = new LateBloomer();

flower.bloom();  // A second later, call the'declare'method

ES3 version of bind() method

The idea of zyx456 is to merge bind() and function parameters. Then run apply.

if (!Function.prototype.bind) {
    Function.prototype.bind = function (o) {
        var self = this, arg = Array.prototype.slice.call(arguments, 1);

        var fbind = function () {
            var arr = [...arg, ...arguments];
            // Now call self as a method of o and pass in these arguments
            return self.apply(o, arr);
        };
        fbind.prototype = this.prototype;//For the bind constructor.
        return fbind;
    };
}

Posted by Jarl on Mon, 22 Jul 2019 08:09:44 -0700