We understand the inheritance of prototype through [[prototype]], proto and Prototype.
[[prototype]]
The ECMAScript standard states that every object has a built-in attribute [[prototype]] that points to an object’s prototype object. When looking for an object’s property or method, if it is not found on the current object, it looks on its prototype object, if not on the prototype object, it looks on the prototype object of the prototype object, and so on until the prototype object of an object is NULL (null has no prototype). As you can see, this kind of layer up lookup is a chain lookup. At each layer, the object has a link to its prototype object ([[prototype]]). The whole chain made up of these links is called the prototype chain.
As shown in Figure 1, the idea of prototype chain search is roughly as follows:
- When object1 looks for an attribute, it first looks for the attribute it owns. If not, it looks for the attribute in object1
__proto__
([[prototype]]
) at this time__proto__
Pointing to the object2. - If the object object2 does not have an attribute to look for, the
__proto__
If not, continue to look up. - Up to the prototype of the Object Object
__proto__
If the value is null, no search is performed.
Builts-in is used to build built-in functions such as toString(), valueOf, etc.
__proto__
[[Prototype]] is a built-in attribute. We can’t get it directly. Many browsers implement object.prototype.__proto__. __proto__ and [[Prototype]] are essentially the same thing, both pointing to an object’s Prototype object. On the other hand, setting [[Prototype]] is a slow operation that affects performance, so using __proto__ is debatable, and using Object.getProtoTypeof and Object.setProtoTypeof is more recommended for accessing Prototype objects (however, If performance is an issue, avoid it).
prototype
Prototype is a property of constructors (an object with [[Construct]] inner methods), such as functions (non-arrow functions). Instance objects do not have this property. The prototype object is considered a normal object inside the constructor (or pointing to a normal object), but is unfortunately called prototype. When the constructor executes, Constructor prototype is automatically assigned to __proto__(if no object is returned inside the constructor) so that constructor prototype and properties on the prototype chain can be shared on the new instance. Prototype is a completely different concept from __proto__ and [[prototype]], and the common confusion comes from using the term prototype object to refer to different objects.
Animal gets access to the prototype property food and eat from the object instantiated by new.
var Animal = function(name) {
this.name = name;
};
Animal.prototype.food = 'meat';
Animal.prototype.eat = function() {
console.log(this.name + ' eat ' + this.food);
};
var panda = new Animal('panda');
var dog = new Animal('dog');
console.log(panda.eat()); // panda eat meat
console.log(dog.eat()); // dog eat meat
console.log(panda.__proto__=== Animal.prototype); // true
Copy the code
As shown in the following figure, panda and dog can access the food and eat attributes on the Animal prototype because Animal’s prototype object is assigned its __proto__ property when the constructor is called. If the instance object does not find its own method (panda.eat), it will look in the __proto__ object, and this object happens to be the Animal prototype object, it has eat method, so it can successfully access eat method.
Uncaught TypeError: / / Fish prototype = Animal; / / Fish prototype = Animal; Nimo.eat is not a function. This error occurs because we mistake __proto__ as a prototype object. We have already seen that inheritance is implemented through a chain of archetypes, which in turn is concatenated by __proto__. When Fish’s prototype is set to Animal, nimo’s __proto__ is Animal. Eat = Animal Animal __proto__ (eat) ¶ Animal __proto__ (eat) ¶ Animal __proto__ (eat) ¶
var Animal = function(name) {
this.name = name;
};
Animal.prototype.food = 'meat';
Animal.prototype.eat = function() {
console.log('I can eat' + this.food);
};
var Fish = function(name) {
this.name = name;
};
Fish.prototype = Animal;
var nimo = new Fish('nimo');
console.log(nimo.eat()); // Uncaught TypeError: nimo.eat is not a function
Copy the code
Create objects and prototype chains in different ways
-
Syntax structure creates objects
-
Object literals
Object literals create objects whose prototype chain is obj –> object. prototype –> null
var obj = { a: 1 }; Copy the code
-
Array literals
Prototype –> Object. Prototype –> null
var arr = [1, 2]; Copy the code
-
Function literal
Prototype –> Object. Prototype –> null
function f(){ console.log('func'); }Copy the code
-
-
The constructor creates objects
Prototype –> Object. Prototype –> null
var Animal = function(name) { this.name = name; }; Animal.prototype.food = 'meat'; Animal.prototype.eat = function() { console.log('I can eat' + this.food); }; Prototype var panda = new Animal('panda');Copy the code
-
Object.create Creates an Object
In ES5, a new method was introduced to create objects, object.create, where the prototype of the new Object is the first argument passed in.
var a = { x: 1 }; // a --> Object.prototype --> null var b = Object.create(a); // b --> a --> Object.prototype --> null console.log(b.__proto__ === a); // true console.log(b.x); // 1 var c = Object.create(b); // c --> b --> a --> Object.prototype --> null console.log(c.__proto__ === b); // true Copy the code
conclusion
- Any object can be a prototype object for another object (
__proto__
Object to point to). [[Prototype]]
A built-in property that points to the prototype object for an object and cannot be accessed directly.__proto__
A property that is implemented for a non-standard, but only for easy access to the prototype object, and[[Prototype]]
They’re essentially the same as pointing to the prototype object, and they’re properties that all objects have.- The prototype for a
[[construct]]
The property of the object of the inner method, which is itself just a normal object, just happens to be called a prototype object, and its purpose is to assign the so-called prototype object to the instance when the constructor generates a new instance__proto__
Property so that new instances can pass through__proto__
To inherit the methods in the constructor prototype. You can see prototype and__proto__
The prototype object referred to is a completely different concept. - The instance object has no Prototype property,