The constructor

What is a constructor?

Constructor returns a reference to the constructor when the instance object is returned. The value of this attribute is a reference to the function itself, not a string containing the name of the function.


function Dog(color){
    this.color = color
}

const dog = new Dog('red')
dog.constructor === Dog // true

Copy the code

A constructor is a function in itself, no different from a normal function, but it is usually capitalized for the sake of specification. The difference between a constructor and a normal function is that a function that generates an instance using new is a constructor and calls a normal function directly.

What is the constructor attribute of an instance created by a normal function?

function Dog(color){
    return {color: color}
}
const dog2 = Dog('blue')

dog2.constructor === Object // true
Copy the code

The prototype

Each object has a prototype object that is modelled on its prototype and inherits methods and properties defined on the Prototype property of the object’s constructor function rather than the object instance itself.

Three formulas for prototype summarization:

  1. Object.__proto__ === its constructor. Prototype

  2. Object. Prototype is the (direct or indirect) prototype of all objects

  3. All functions are constructed by Function.

Prototype chain

Each instance object has a private attribute (called __proto__) that points to its constructor’s prototype. The prototype object also has a prototype object of its own (__proto__), cascading up until an object’s prototype object is null. This relationship is called the prototype chain.

function Dog(color) {
    this.color = color
}
const dog3 = new Dog('green')

dog3.__proto__ === Dog.prototype // true
dog3.__proto__.__proto__ === Object.prototype // true
dog3.__proto__.__proto__.__proto__ === null // true
Copy the code

About the role of new when instantiating objects through constructors.

  1. Creates an empty object as an instance of the object to be returned.

  2. Point the empty object’s prototype to the constructor’s Prototype property.

  3. Assign the empty object to the this keyword inside the function.

  4. Start executing the constructor internal code.

Simulation implementation new

function create() {
    // Create an empty object
    var obj = new Object(),
    // Get the constructor passed in (arguments can be obtained by removing the first argument)
    Constructor = [].shift.call(arguments);
    // Link to the prototype, obj can access properties in the constructor prototype
    obj.__proto__ = Constructor.prototype;
    // // binds this to implement inheritance, and obj has access to properties in the constructor
    Constructor.apply(obj, arguments);
    // Return the object
    return obj;

};
Copy the code

The above code is almost complete, but you can continue to optimize

The constructor returns a value in three cases:

  1. Return an object
function Dog(color, name) {
    this.color = color;
    return {
        name: name
    }
}

const dog = new Dog("black"."Flower");
dog.color;
// undefined

dog.name;
// ""
Copy the code

Only properties in the returned object can be accessed in the instance dog

  1. There is noreturnThat returnundefined
function Dog(color, name) {
    this.color = color;
}

const dog = new Dog("black"."Flower");
dog.color;
// 'black'

dog.name;
// undefined
Copy the code

In instance dog, only properties in the constructor are accessible, as opposed to case 1.

  1. returnundefinedOther basic types
function Dog(color, name) {
    this.color = color;
    return 'i miss you'
}

const dog = new Dog("black"."Flower");
dog.color;
// 'black'

dog.name;
// undefined
Copy the code

In instance dog, only properties in the constructor can be accessed, and the structure is equivalent to no return value.

So we also need to determine if the value returned is an object, and if it is, we return that object, or we return the newly created obj object.

So optimize the code:

function create() {
   
    var obj = new Object(),
    
    Constructor = [].shift.call(arguments);
  
    obj.__proto__ = Constructor.prototype;
 
    const result = Constructor.apply(obj, arguments);
    
    return result instanceof Object ? result : obj;

};
Copy the code