Some time ago, a friend of mine was interviewed and was asked a question: Write a JS method to implement a new operator. In my friend’s heart there were ten thousand grass-mud horses galloping through…… . New is used to create instance objects, but we don’t pay much attention to what happens behind the new operation.

newBehind the operation

The new operator creates an instance of a user-defined object type or of a built-in object with a constructor. The new keyword does the following: 1. Creates an empty simple JavaScript object (that is {}); 2. Link this object (that is, set its constructor) to another object; 3. Use the new object created in Step 1 as the context for this. 4. If the function returns no object, return this.

The above description gives us a clear idea of what is going on behind a simple new operator. Now let’s look at the following code

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

Car.prototype={
  getMake: function() {
    return this.make
  }
}

var car = new Car('Eagle'.'Talon TSi'.1993)
Copy the code

Var car = new car (‘Eagle’, ‘Talon TSi’, 1993

Step 1: Create a simple empty object

var obj = {}
Copy the code

Step 2: Link this object to another object (prototype chain)

// Set the prototype chain
obj.__proto__ = Car.prototype
Copy the code

Step 3: Use the new object created in Step 1 as the context for this

// This points to the obj object
Car.apply(obj, ['Eagle'.'Talon TSi'.1993])
Copy the code

Step 4: If the function does not return an object, return this

// Since Car() does not return a value, obj is returned
var car = obj
car.getMake() // 'Eagle'
Copy the code

Note that Car() returns the value if it has a return

var rtnObj = {}
function Car(make, model, year) {
  // todo
  // ...
  // Return an object
  return rtnObj
}

var car = new Car('Eagle'.'Talon TSi'.1993)
console.log(car === rtnObj) // true
Copy the code

Encapsulate a method

Now we wrap the above steps into an object instantiation method

function objectFactory(){
    var obj = {};
    // Get the first argument of the method (and remove the first argument), which is the constructor
    var Constructor = [].shift.apply(arguments);
    // Point the new object's internal attribute __proto__ to the constructor's prototype, so that the new object can access the properties and methods in the prototype
    obj.__proto__ = Constructor.prototype;
    // Get the return value of the constructor
    var ret = Constructor.apply(obj, arguments);
    Return an object if the return value is an object, otherwise return an instance object of the constructor
    return typeof ret === "object" ? ret : obj;
}
Copy the code

class

Es6 has added the new keyword class. If function is changed to class, what will happen? The result is the same.

class Car {
  constructor(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
  }
  getMake() {
    return this.make
  }
}

var car = objectFactory(Car, 'Eagle'.'Talon TSi'.1993)
car.getMake() // 'Eagle'
Copy the code

summary

Now do you understand what a new instance of JS does? Seemingly simple an operator, behind the implementation is not so simple, need to savor the essence.

Pay attention to our