Before we talk about prototypes and prototype chains, let’s get started with a few things:

  1. All objects are generated by the new function. This includes let obj = {}, which is syntax sugar and is essentially generated by let obj = new Object(). So how does the function get generated? It is clear from the figure that the Function is essentially generated by new Function, although we would not normally write it this way and certainly do not recommend writing it this way

    function Test(){}
    / / equivalent to
    let Test = new Function(a);Copy the code

    So who generated Function? Function a Function is also a Function. We just said that a Function is generated by new Function, but it is a special case that is not created by anything. It is added directly to memory when the JS engine starts.

  2. All functions are also objects, and since they are objects, functions must have properties. For example: array. form, array. isArray, etc

  3. Object is a reference type.

🍇 prototypeprototype

All functions have an attribute: prototype, called the function prototype. Functions are automatically created with the prototype attribute.

So what is a prototype?

By default, Prototype is a plain object.

By default, Prototype has an attribute: constructor, which is also an object pointing to the constructor itself.

Each function (add, Object, Array, nothing) has a constructor property that points to the function’s prototype. The function’s prototype also has a constructor property. It is also an object, and constructor points to the constructor itself.

So what’s the use of a prototype? Stereotypes by themselves are useless, but implicit stereotypes are useful, right

🍄 Implicit archetypes__proto__

All objects have one attribute, __proto__, called implicit archetypes. The two underscores indicate system private properties. Do not touch them lightly.

By default, an implicit stereotype refers to the stereotype of the function that created the object. This is particularly important because it relates implicit archetypes to archetypes. What does that mean?

For example 🌰 :

function Test(){}let obj = new Test();
// obj.__proto__ === Test.prototype; Returns true
Copy the code

For example 🌰 :

function Test(){
    return {};// where {} is syntactic sugar, it is essentially created with new Object()
}
let obj = new Test();Let obj = new Object();
// obj.__proto__ === Object.prototype; Returns true
Copy the code

Now that we know who the implicit prototype points to, we plot the relationship between prototype, constructor, and __proto__ as follows:

In the previous section, we said that all objects are created using the new function, so we have the above relationship. The __proto__ of object 1, __proto__ of object 2, and the prototype of function add all refer to the same block of memory. This explains why we write functions on the prototype. Any object created through the add constructor can access this function.

function Add(name,age){
       this.name = name;
       this.age = age;
 }

Add.prototype.say = function(){
     console.log("Forensic".this.name,this.age)
}
let obj1 = new Add("Front-end hunter.".18);
let obj2 = new Add("Post mortem examiner".20);
 
 obj1.say(); // Forensic front-end hunter 18
 obj2.say(); // Forensic coroner
Copy the code

Object members are accessed in the following order: first, the object is checked to see if the property or method exists in the current object, if so, it is used directly, otherwise it continues to search down the prototype chain.

A paragraph in the MDN document reads:

Link to see

Has inherited Array. The prototype is because of the existence of implicit stereotype, it is also suggests that in the future to write on the prototype object need to share things, especially the function, this kind of behavior have a interesting name, called the monkey patch, perhaps because 🐒 imitative, add members to the prototype, to strengthen the function of objects, But there are also disadvantages, will cause prototype pollution, so or cautious use.

🍓 prototype chain

Once we get this picture straight, we’ll understand what a prototype chain is, so let’s go through it together

  1. In the prototype section we said that all functions have a property called prototype, so the prototype of the Object function points to the Object prototype. Similarly, the prototype of our custom function must point to the prototype of our custom function. There is a special point here. The Function Function, which has nothing to create, is added directly to memory when the JS engine starts, so the Function Function points directly to the Function prototype.

  2. So if you look at the green line, the green line is new, and you know that all functions are created by new Function(), so Function refers to Object and custom Function, and there’s a line in the graph where custom functions refer to custom objects, and we said at the beginning of this article, All objects are created using the new function, the code says:

        function Test(){}let obj = new Test();// Obj can represent a custom object in the graph
    Copy the code
  3. And finally, the blue line, the blue line is the implicit stereotype, and as I said in the implicit stereotype section, all objects have a property __proto__, so functions are objects, so who does the implicit stereotype point to? To understand that an implicit stereotype refers to the prototype of the function that created the object, we have to know who created the function? What is the prototype of who? All functions are created by Function functions, and the prototype of Function Function points to Function prototype, which is a special point, so the implicit prototype of Object and custom functions points to Function prototype, Function Function is also a Function, and since nobody created it, Is added directly to memory, and its prototype points to the Function prototype, which is also a special point.

       function Test(){}
       / / equivalent to
       let Test = new Function(a); Test.__proto__ ===Function.prototype; // true
    Copy the code

    We all know that all functions have members in common, such as call, apply, bind, etc. We do not add these members to custom functions, so why do we use them? This is because all the implicit stereotypes of functions point to the prototype of Function, and these methods exist on the prototype of Function, so every Function can use these members, which is the effect of inheritance.

    A custom function can create a custom object with new, and a custom object is also an object, so there must be an implicit prototype __proto__ that points to the prototype of the function that created the object, so the implicit prototype of the custom object points to the prototype of the custom function, so who does the prototype point to? I don’t know if you remember what I said in the prototype section: By default, prototype is a normal Object Object, so we can assume that prototype is created by new Object(), so prototype is an Object.

        function test(){};// Custom functions
        
        test.prototype.__proto__ === Object.prototype;// true    
    Copy the code

    📣 special point: the implicit prototype of Object’s prototype points to null, object.prototype. __proto__ === null, returning true

    So now you know what a stereotype chain is, where the implicit stereotype of a custom Object points to the stereotype of a custom function, and the implicit stereotype of a custom function points to Object, and Object points to NULL, and that’s a stereotype chain, right

Self test question one: you can try to do it, and then you can check according to the last picture

function Fayi() {}
Fayi.prototype.camel = function() {}

var u1 = new Fayi();
var u2 = new Fayi();

console.log(u1.camel === u2.camel); 
console.log(Fayi.prototype.constructor);
console.log(Fayi.prototype === Function.prototype);
console.log(Fayi.__proto__ === Function.prototype); 
console.log(Fayi.__proto__ === Function.__proto__); 
console.log(u1.__proto__ === u2.__proto__);  
console.log(u1.__proto__ === Fayi.__proto__); 
console.log(Function.__proto__ === Object.__proto__);
console.log(Function.prototype.__proto__ === Object.prototype.__proto__);
console.log(Function.prototype.__proto__ === Object.prototype); 
Copy the code

😊 ok, the above is my share, friends click a “like” and then go 👍 support oh ~ 😘, I will be more motivated 🤞