AKA__proto__.prototype.constructorLove and hate

conclusion

__proto__

  • __proto__Properties are unique to the object
  • It points from object to object, by default pointing to its prototype object (parent object),
  • When accessing a property of an object, if the property does not exist inside the object, the object will be removed__proto__Pointer to the prototype Object (parent Object), keep looking until you find the source of all things Object__proto__Property of Object__proto__It points to null, at which point it is at the end and does not have the property. so__proto__The endpoint of the property is NULL
  • through__proto__The link that connects the layers of objects they point to is called a prototype chain

prototype

  • prototypeProperties are unique to functions and are created by default when any function is createdprototypeobject
  • It points from a function to an object, and its meaning is the prototype object of the function. It can also be understood as a prototype object for instances of this class of objects (instances created through this function)
  • Its purpose is to store properties and methods shared by all instances of this class of objects, essentially to save memory

constructor

  • constructorIs unique to the object
  • It points from an object to a function, and by default points to the object’s constructor. Each object can be found corresponding toconstructor, because the premise of creating an object is to haveconstructorIt may be owned or inherited. Single fromconstructorFor this property, onlyprototypeObjects have.
  • constructorIt’s easy to change, so it’s less reliable
  • FunctionThis object (also a function) is special, and its constructor is itself. All functions and objects are ultimately created byFunctionConstructor, soconstructorThe end point of the property isFunctionThis function

Prototype formula

// Demo
function Fun() {};
let fn = new Fun();
Copy the code

fn.__proto__ === Fun.prototype

fn.constructor === Fun

fn.__proto__.constructor === Fun

Fun.prototype.constructor === Fun

Fun.constructor === Function

Function.constructor === Function

Function.__proto__ === Function.prototype

Fun.prototype.__proto__ === Object.prototype

Function.prototype.__proto__ === Object.prototype

Object.prototype.__proto__ === null

Object.constructor === Function


The __proto__ and constructor properties are prototype properties unique to objects and functions, but since functions are also objects in JS, functions also have __proto__ and constructor properties

The illustration

__proto__Attribute diagram

prototypeAttribute diagram

constructorAttribute diagram

constructorIn combination with__proto__The illustration

Summary diagram

Writing anewHave a try

First, we need to know what new does:

  • Create a new object, obj
  • Object obj__proto__Property points to the constructor’s prototype objectprototype
  • Execute the constructor and pass the argument to change the reference of this to the newly generated object obj
  • If the constructor itself has a return value, and the return value is an object type, return the return value. Otherwise, return the new object obj(according to the specification, return null and undefined, still return obj).
// write (1)
// If the first argument is not a function, an exception is thrown, since only functions have prototype objects by default
// Use object.create () to create a new Object with the [[Prototype]] you want.
// Execute the constructor and pass the argument this to obj
// If the constructor itself has a return value, and the return value is an object type, return the return value; Otherwise return the new object obj
function _new(Ctor, ... arg) {
    if(typeofCtor ! = ='function') {
        throw `the first param must be a function` 
    }
    let obj = Object.create(Ctor.prototype);
    let ret = Ctor.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}


// Define the constructor
function Person(name = 'sakura') {
    this.name = name;
    console.log(this.name);
}

let person1 = _new(Person, 'eril'); // eril
let person2 = new Person('eril'); // eril
Copy the code
// The other way around
function _new2() {
    let obj = Object.create(null); // Create a pure empty object
    let Constructor = [].shift.call(arguments); // Intercepts the first argument in the argument list as a constructor. After execution, the argument list length is -1
    Object.setPrototypeOf(obj, Constructor.prototype); // The more recommended way to set the object prototype, after execution, inheritance relationship established
    let rt = Constructor.apply(obj, arguments); // Execute the constructor and point this to obj
    return typeof rt === 'object' ? rt : obj; // Check whether the constructor returns an object, if so, return the constructor return value, otherwise return the newly created object obj
    
}

function _new3(func) {
    var res = {};
    if(func.prototype ! = =null) {
        res.__proto__ = func.prototype; // Obsolete and not recommended methods for modifying prototype objects
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments.1)); // truncate the first argument (constructor)
    // According to the specification, null and undefined are returned, and obj is still returned
    if ((typeof ret === "object" || typeof ret === "function") && ret ! = =null) {
        return ret;
    }
    return res;
}
Copy the code

Thank you

Help you understand prototype, __proto__ and constructor thoroughly

Understand constructor, Prototype, __proto__, and prototype chains in your own way