The implementation principle of new, call, apply and bind methods

Time:2020-10-18

We often use new, call, apply, bind and other methods in JavaScript. They are indispensable in scenarios such as pseudo array to array, function parameter transfer and inheritance. Here we will not discuss their use methods in detail. We will study their implementation methods and rewrite our own methods, so that we can re understand their implementation process, so that we can know what they are and why they are in development!

Implementation of new

We use new to instantiate a constructor to generate an instance object. What does new do, mainly in the following five steps:

  • 1: Get constructor
  • 2: Create a new object;
  • 3: The scope of the function is assigned to a new object (in this case, a new context is actually produced)
  • 4: Execute code in function (add properties and methods for new objects)
  • 5: Return value. If there is no return value or a non object value, the new object created will be returned, otherwise the return value will be returned as a new object. (that is to say, an object will be returned, and the conclusion can be drawn from the following code.)
function MyNew() {
      let Constructor =  Array.prototype.shift . call (arguments); // 1: take out the constructor

      Let obj = {} // 2: execution creates a new object

      obj.__ proto__  = Constructor.prototype  //3: the prototype of the object is equal to the constructor prototype

      var result =  Constructor.apply (obj, arguments) // 4: execute the code in the function

      Return typeof result = = ='object '? Result: Obj // 5: the returned value must be an object
    }
  • Verification of mynew method
    function Man(name, age) {
      this.name = name
      this.age = age
    }
    var tom = new Man('tom', 20)
    var mike = MyNew(Man, 'mike', 30)
    console.log(tom  instanceof Man, mike instanceof Man) // true true

The implementation of call

There are three steps to implement the call method, such as fn.call(obj, a, b)

  • 1: Point the context of calling function fn to obj
  • 2: Formal parameters a, B, etc. are passed in by commas
  • 3: Execute the function fn and return the result
Function.prototype.myCall = function (context) {
      context = context ? Object(context) : window 
      context.fn  =This // reset context
      Let args = [... Arguments]. Slice (1) // intercept parameters a, B
      let r =  context.fn (... Args) // execute function
      delete  context.fn  //Delete attributes to avoid contamination
      Return R // the result is returned
    }
  • Verification of mycall method
//Under browser environment
    var a = 1, b = 2;
    var obj ={a: 10,  b: 20}
    function test(key1, key2){
      console.log(this[key1] + this[key2]) 
    }
    test('a', 'b') // 3
    test.myCall(obj, 'a', 'b') // 30

Implementation of apply

The only difference between the apply method and the call method is that the parameter passed in by apply is an array format.

//Apply principle
    Function.prototype.myApply = function (context) {
      context = context ? Object(context) : window
      context.fn = this
      let args = [...arguments][1]
      if (!args) {
        return context.fn()
      }
      let r = context.fn(...args)
      delete context.fn;
      return r
    }
  • Apply method verification
//Under browser environment
    var a = 1, b = 2;
    var obj ={a: 10,  b: 20}
    function test(key1, key2){
      console.log(this[key1] + this[key2]) 
    }
    test('a', 'b') // 3
    test.myCall (obj, ['a ','b'] // 30 note that this is the incoming array ['a ','b']

Implementation of bind method

The difference between the bind method and the call and apply methods is that they both change the context, but bind does not execute the function immediately.

//Bind principle
    Function.prototype.Mybind = function (context) {
      let _me = this
      return function () {
        return _me.apply(context)
      }
    }
  • Bind method verification
    var a = 1, b = 2;
    var obj ={a: 10,  b: 20}
    function test(key1, key2){
      console.log(this[key1] + this[key2]) 
    }
    var fn = test.bind(obj)
    fn('a', 'b') // 30

Well, after the introduction, if you think it’s helpful for you, please click zanha, haha!

Reference article source:

  • Nuggets: principles of call, apply, bind, new