Prototype objects and prototype chains are not used explicitly in front-end work, but they are also used implicitly, such as jquery, Vue, etc. __proto__, prototype, __proto__, __proto__, __proto__, __proto__, __proto__, __proto__, __proto__

The original is here

Question and answer session

How does Javascript create objects?

You might say factory pattern, constructor pattern, stereotype pattern, composite constructor and stereotype pattern, dynamic stereotype pattern, parasitic constructor pattern, and safe constructor pattern, but we can categorize them as function-creating objects.

We can simply divide Object creation into three ways: function creation Object, literal creation, Object creation. Of course, there are just two classes: function created objects and literals created objects, because Object in New Object() is itself a function.

Object // f Object(){ [native code] }
Copy the code

What is a prototype?

The prototype property refers to a Prototype object. The prototype property refers to a prototype object. The prototype property and the prototype object are two different things. Expressed in pseudocode as follows:

var function{
	prototype: prototype{} // Function's prototype property points to the prototype object
}
Copy the code

Function has the prototype property. The new object does not have the prototype property.

# function function Fun(name){ this.name = name; } prototype // {constructor:f} var Fun = new Fun(' constructor '); fun.prototype // undefined # Object Object.prototype // {constructor:f,__defineGetter__:f,... } var object = new Object(); Var jack = {}; var jack = {}; jack.prototype // undefinedCopy the code

What is __proto__?

In the official ES5 class, we define a property called [[prototype]]. Every object (except null) has a property called [[prototype]]. This property is a pointer to a memory heap named prototype object. Prototype is also an Object, so it has its own [[prototype]] property that points to the next prototype and ends in our Object.prototype Object.

Note that ⚠️ uses [[prototype]] instead of __proto__. But they’re the same thing: [[prototype]] is the official attribute, and __proto__ is the browser’s own implementation of [[prototype]].

The internal __proto__ of an object can be described in three ways:

  1. Define a normal object using a literal: var foo = {}
  2. Create a function: function Foo(){};Contains the Object ()
  3. Create an object instance: var foo = new foo ();

Case 1: {}

var foo = {};
foo.__proto__; / / {}
foo.__proto__ === Object.prototype; // true
foo.hasOwnProperty('prototype'); // The false function has the prototype attribute
foo.hasOwnProperty('__proto__'); // false
Object.prototype.hasOwnProperty('__proto__'); // true
Copy the code

On the last line of the code, one returns false and the other returns true. ⚠️ because it doesn’t exist in foo (foo.__proto__) or foo.prototype (foo.prototype. __proto__) or foo (foo.__proto__), in fact, It comes from Object.prototype and is more of a getter/setter than a property.

Function Foo(){}

1. function Foo(){};
2. Foo.__proto__; // [Function]
3. Foo.__proto__ === Object.prototype; // false
4. Foo.__proto__.__proto__ === Object.prototype; // true
5. Foo.prototype.__proto__ === Object.prototype; // the prototype object pointing to the true function
6. Foo.__proto__ == Foo.prototype; //false
7. Foo.hasOwnProperty('__proto__'); // false
8. Foo.hasOwnProperty('prototype'); // true
Copy the code

In the function, Foo.__proto__ can be interpreted as referring to Foo. Prototype, but in fact the two are different. Then each function has a default prototype property that points to the function’s prototype object.

Object instance new Foo()

function Foo(){};
var foo = new Foo();
foo.__proto__; // Foo {}
foo.__proto__ === Foo.prototype ; true
foo.hasOwnProperty('prototype'); false
foo.hasOwnProperty('__proto__'); false
Copy the code

The prototype attribute is created by default only in functions and refers to the corresponding function prototype object.

What does constructor mean?

In the javascript language, the constructor property is designed specifically for functions and exists in the prototype property of every function. This constructor holds a reference to the function.

Function F(){// some code} # Add a prototype attribute # 2 to this function. Add an additional constructor attribute to the Prototype object, which holds a reference to function FCopy the code

Object instances also have a constructor attribute (obtained from Prototype). Each object instance has access to its constructor from the constructor object, as follows:

var f = new F();
f.constructor === F; // true
f.constructor === F.prototype.constructor; // true
Copy the code

Now that we have access to the instance’s type, f.constructor, we can do something special with the instance:

if(f.constructor == F){
	// some code
}
Copy the code

Don’t do this though, because constructor is unstable (see what constructor does in this object). Instead of taking the above action, you can use instanceof:

if(f instanceof F){
	// some code
}
Copy the code

What does constructor do in the object?

Here is a copy of Mr. He’s answer.

The constructor property does not affect any javascript internal properties. Instanceof checks the prototype chain of objects, which you can't normally modify (though some engines are exposed via a private __proto__ attribute).

Constructor is nothing but a relic of javascript language design. Since the constructor property can be changed, it doesn't necessarily point to the object's constructor, just a hint. However, as a programming convention, we should try to maintain this habit by pointing the object's constructor to its constructor.

Example:

delete Object.prototype.constructor; // true
({}).constructor; // undefined
({}) instanceof Object; // true
Copy the code

What is the highest point of the prototype chain?

Javascript Advanced Programming states that the default prototype for all functions is an instance of Object, so the default prototype contains an internal pointer to Object.prototype. So the highest point of the prototype is Object? You can say Object, but I think it’s null.

Object.prototype.__proto__; // null
Object.prototype.__proto__===null ; // true
Copy the code

The highest point is Object/ NULL, which is harmless.

The relationship between instance and prototype?

When reading the properties of an instance, if the properties of the instance cannot be found, it looks for the properties of the stereotype associated with the object, and if it still cannot, it looks for the stereotype, all the way to the top level.

function Person(){
}
Person.prototype.name = "Jiaming";

var person = new Person();

person.name = "jiaming";
console.log(person.name); // "jiaming"

// Delete the attributes of the instance
delete person.name;
console.log(person.name); // ""

// Add an attribute to __proto__ to override the original
person.__proto__.name = "Jia";
console.log(person.name); __proto__ is implemented by the browser manufacturer and is not standard

// Add a question __proto__ to add attributes or methods that are placed on the object's prototype
var another_person = new Person();
console.log(another_person.name); // The "chia" proof is placed on the object's prototype
Copy the code

The prototype of the prototype?

If a property or method is not found in your prototype, go to the prototype to find it. As mentioned earlier, the default prototype for all functions is an instance of Object, so the default prototype contains an internal pointer to Object.prototype.

Function Person(){} var Person = new Person(){Person = new Person(){Person = new Person(){Person = new Person(){Person = new Person(){Person = new Person(); The prototype of the constructor then points to the prototype of Object, that is, person.prototype. __proto__ points to Object.prototype.

Conclusion the bai

Well, for constructors, let’s put everything together. The above are pure text instructions, below with pictures to understand.

First, the relevant code:

function Person(name){
	this.name = name;
}
Person.prototype.sayName = function(){
	console.log(this.name);
}

var person = new Person("Jiaming");
person.age = 12;
person.sayName(); // ""
console.log(person.name.toString()); // ""

var another_person = new Person("jiaming");
another_person.sayName();
Copy the code

In the code above, the correlation is shown below

The link

The small demo uses canvas to draw small starlight. The code is as follows:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>canvas</title>
    <style>
        body{
            margin: 0;
            padding: 0;
            position: relative;
        }
        #myCanvas{
            position: absolute;
            left: 50%;
            top: 50%;
            background: # 000;
            margin-left: -300px;
            margin-top: -150px;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="600" height="300" style="border: 1px solid #000;">

    </canvas>
    <script src="path/to/canvas.js"></script>
</body>
</html>
Copy the code
window.onload = function(){
    var c = document.getElementById('myCanvas');

    var grd = ""; // Gradient color

    / / context
    var context = c.getContext("2d");
    
    if(context){
        // x,y,r coordinates and radius
        function Star(x,y,r){
            this.x = x;
            this.y = y;
            this.r = r;
            this.init(this.x,this.y,this.r);
        }
        
        // Draw stars
        Star.prototype.init = function(x,y,r){
        
        
            context.beginPath();
        
            // Gradient color
            grd = context.createRadialGradient(x,y,r2 -,x,y,r+2)
            grd.addColorStop(0.'white');
            grd.addColorStop(1.'yellow');
            context.fillStyle=grd;
        
            / / draw circles
            context.arc(x,y,r,0.2*Math.PI);
        
            // Fill the color
            context.fill();
        
            context.closePath();
        
        
        }
        
        // Create a star
        for(var i = 0; i < 300; i++){
            var x = Math.floor(Math.random()*600);
            var y = Math.floor(Math.random()*300);
            var r = Math.floor(Math.random()*3) +2;
            new Star(x,y,r)
        }
    }else{
        var div = document.createElement("div");
        div.innerHTML = "Your browser does not support Canvas, please upgrade your browser!";
        document.getElementsByTagName("body") [0].appendChild(div); }}Copy the code

The simple effect is as follows:

The original is here