From MDN, we know:

  • The new operator defines an object type or instance of a constructor’s built-in object.

  • Syntax for the new operator: new Constructor([arguments]), where Constructor is a class or function with an object instance and arguments are optional.

function Dog() {
  // This refers to an instance of Dog
  this.name = 'lucky';
  this.color = 'black';
}

// Dog is undefined
// The Dog function returns undefined by default when no return is specified
var dog = Dog();

// dogInst now has the name, color and other attributes
// The new operator "manipulated" this so that dogInst has the name and color attributes
var dogInst = new Dog();
Copy the code

So what does new Dog() do behind the scenes here? But you can see from the above example:

  • How the constructor is called affects the final result;
  • newThe invocation has changedthisThe point to(Apply, call, bind);

We can analyze what happens inside the new operator by implementing a new operator that mimics its behavior:

function Dog(name) {
  this.name = name;
  / /... other properties
}

function New(Ctor) {
  // Create a new object
  // Note: Arguments are arrays of classes and need to borrow the slice method on the Array instance
  // in es6, we can use spread syntax (... IterableObj) handles arguments objects
  var o = Object.create(null);

  // In the second step, the new object inherits all attributes from the constructor prototype
  o.__proto__ = Ctor.prototype;

  var args = Array.prototype.slice.call(arguments.1);

  // Execute the constructor to add all attributes to the newly created object
  var res = Ctor.apply(o, args);

  // Step 4, determine how to execute the constructor, return the corresponding result
  return Object.prototype.toString.call(res) === '[object Object]' ? res : o;
}

var dogInst = New(Dog, 'lucky');
Copy the code

conclusion

There are four steps to creating the new operator:

  1. Create a new object(Object.create(null) with no prototype). The purpose is to preservenewAll properties of the instance that comes out;
  2. Assigns the constructor’s stereotype to the newly created object’s stereotype. The goal is to inherit properties from the constructor prototype;
  3. Call the constructor and put the innerthisPoint to the newly created object. The goal is to have all the attributes in the constructor transferred to the object, instead of making thethisThere are three ways to point to change:Apply, call, bind;
  4. Determine how the constructor is called, if yesnew, returns the new object after processing, if it is normal call, returns the return value of the constructor call directly;

summary

Problems that once seemed difficult can’t stand the careful consideration of time, so they need more thinking.