Understanding the use and implementation of bind methods

Method Description

The bind() method creates a new function that, when called, sets its this keyword to the value provided.

Grammar Description

fn.bind(thisArg,arg1,arg2,..)

Parameter Description

thisArg: When a bound function is called, this parameter points to this as the original function runs.This parameter is invalid when a binding function is called with the new operator.
arg1,arg2,...When a bound function is called, these parameters are passed to the bound method.

Application Scenarios

1. Create binding methods

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // Return 81

var retrieveX = module.getX;
retrieveX(); // Return 9, in which case, "this" points to the global scope

// Create a new function to bind "this" to a module object
// Beginners may be confused by global x variables and property X in module s
var boundGetX = retrieveX.bind(module);
boundGetX(); // Return 81

2. Partial Functions
Another simple use of bind() is to have a function with preset initial parameters.These parameters follow this as the second argument to bind (), then they are inserted at the beginning of the parameter list of the target function, and the parameters passed to the binding function follow them.

function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);

var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

3. Cooperate with setTimeout
By default, when window.setTimeout() is used, this keyword points to a window (or global) object.When using the method of a class, this is required to reference an instance of the class, and this needs to be explicitly bound to a callback function to continue using the instance.

4. Binding functions used as constructors
Binding functions are used to construct a new instance created by the target function using the new operator.When a binding function is used to construct a value, the previously provided this is ignored.However, those parameters that were originally provided are still preceded by constructor calls.

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 emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0/*x*/);
// The following line of code is not supported in polyfill.
// It works fine with the native bind method:
//(Note: The bind method of polyfill can also be supported if the first parameter of bind is added, that is, the newly bound this executes Object() to wrap it as an object, and Object(null) is {})
var YAxisPoint = Point.bind(null, 0/*x*/);

var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'

axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new Point(17, 42) instanceof YAxisPoint; // true

Polyfill

The bind() function was added in the fifth edition of ECMA-262; it may not run on all browsers.You can partially add the following code at the beginning of the script to make it work, allowing unsupported browsers to use the bind() feature as well.

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          // When this instance of fNOP === true, the fBound returned is called as a new constructor
          return fToBind.apply(this instanceof fNOP
                 ? this
                 : oThis,
                 // Get the fBound parameter on the call. This is often how the function input parameter returned by bind is passed
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    // Maintain prototype relationships
    if (this.prototype) {
      // Function.prototype doesn't have a prototype property
      fNOP.prototype = this.prototype; 
    }
    // The code below makes fBound.prototype an instance of fNOP, so
    // If the returned fBound is used as the constructor of new, the new object generated by new is passed in as this, and the u proto_u of the new object is an instance of fNOP
    fBound.prototype = new fNOP();

    return fBound;
  };
}
Published an original article. Accepted 2. Visited 10,000+
Private letter follow

Keywords: ECMAScript

Added by Jramz on Mon, 20 Jan 2020 03:58:36 +0200