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.
new
Behind 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.