An in depth understanding of prototype concepts in JavaScript programming

  • 2020-06-22 23:29:28
  • OfStack

JavaScript's prototype objects have always been a struggle. Even experienced JavaScript experts and even its authors often give limited explanations for this concept. I believe the problem comes from our earliest understanding of archetypes. Stereotypes are always closely related to new, constructor, and the confusing prototype attributes. In fact, the prototype is a fairly simple concept. To understand it better, we need to forget about the archetypes we 'learned' and then go back to the source.

What is a prototype?

A stereotype is an object that inherits properties from another object.

Can any object be a prototype?

yes

Which objects have prototypes?

Each object has a default stereotype. The prototype itself is an object, and for every prototype itself there is a prototype. (With one exception, the default object prototype is at the top of each prototype chain, and the other prototypes are behind the prototype chain.)

Take a step back and say, what is an object?

In JavaScript one object is a key/value pair to save any unordered collection, if it is not original class (undefined, null, boolean nuber or string), it is an object.

You can think of an prototype per object. But when I wrote ({}).prototype, I got undefined. Are you crazy?

Forget what you know about the prototype attribute - this is probably the source of confusion. The real prototype for an object is the internal [[Prototype]] attribute. ECMA 5 introduces the standard access method, ES39en.getPrototypeOf (object). This latest implementation has been supported by Firefox, Safari, Chrome and IE9 and, with the exception of IE, all browsers support the non-standard access method of each ___, ES48en__.


var a = {};
 
//Opera  or  IE<=8 The failure 
Object.getPrototypeOf(a); //[object Object]
 
//IE The failure 
a.__proto__; //[object Object]
 
// All browsers 
//(but only if constructor.prototype has not been replaced and fails with Object.create)
a.constructor.prototype; //[object Object]


Very good. false is the primitive type, why does it return a value with ES57en. ___

When accessing a prototype of the original type (prototype), it is forced to convert to an object.


//(works in IE<=8 too, due to double-negative)
false.__proto__ === Boolean(false).__proto__; //true

I want to implement inheritance using prototypes. What should I do now?

It makes little sense to add stereotype attributes to an instance, unless in the first case, it is efficient to add attributes directly to the instance itself


//fails in IE<=8
var a = {};
a.__proto_ = Array.prototype;
a.length; //0

But we can see that the real power of the stereotype is that multiple instances share the same 1 stereotype. The properties of a prototype object are defined only once and can be inherited by all instances it references. The effect of using prototypes on performance and program maintainability is obvious. So is that why constructors come into being? Yes, constructors provide a convenient cross-browser mechanism for common stereotype assignment at instance creation time.


Before I give an example, I need to know what constructor.

Well, first of all, JavaScript doesn't distinguish constructors from other methods, so each method has an prototype attribute. And anything that isn't a method doesn't have that property.


// It's never a constructor method, but it is anyway, right prototype Properties of the 
Math.max.prototype; //[object Object]
 
// Constructors also have prototype attribute 
var A = function(name) {
  this.name = name;
}
A.prototype; //[object Object]
 
//Math not 1 A method, so no prototype attribute 
Math.prototype; //null

You can now define that the prototype property of a method is the object assigned to the instance prototype when the method is used as a constructor to create the instance.

It is important to understand that the prototype attribute of a method has nothing to do with the actual prototype.


//( in IE Would fail in )
var A = function(name) {
  this.name = name;
}
 
A.prototype == A.__proto__; //false
A.__proto__ == Function.prototype; //true - A the prototype Is its constructor prototype attribute 

Can you give me an example?

The following code, which you've probably seen or used a hundred times, is rewritten here, but it might be a bit new.


// The constructor . <em>this</em>  Returns as a new object and its internal [[prototype]] Property will be set to the constructor default prototype attribute 
var Circle = function(radius) {
  this.radius = radius;
  //next line is implicit, added for illustration only
  //this.__proto__ = Circle.prototype;
}
 
// expand  Circle The default prototype The properties of the object therefore extend each new instance created by it prototype Properties of an object 
Circle.prototype.area = function() {
  return Math.PI*this.radius*this.radius;
}
 
// create Circle Each of the two examples will use the same prototype attribute 
var a = new Circle(3), b = new Circle(4);
a.area().toFixed(2); //28.27
b.area().toFixed(2); //50.27

This is great. If I change the prototype property of constructor, can even existing instance objects immediately access the new VERSION of prototype?

HMM... Not exactly. If I've modified the attributes of the existing prototype, this is certainly the case, as the object creation with ES114en. succproto__ refers to the object defined by ES116en. prototype.


var A = function(name) {
  this.name = name;
}
 
var a = new A('alpha');
a.name; //'alpha'
 
A.prototype.x = 23;
 
a.x; //23


But if I replace the prototype attribute with a new object, a. ___ still points to the original object.


var A = function(name) {
  this.name = name;
}
 
var a = new A('alpha');
a.name; //'alpha'
 
A.prototype = {x:23};
 
a.x; //null

What does the default prototype look like?

1 object that has the constructor attribute.


var A = function() {};
A.prototype.constructor == A; //true
 
var a = new A();
a.constructor == A; //true (a  the constructor An attribute inherits from its stereotype )


What is the relationship between instanceof and prototype?
If the prototype attribute of A appears in the prototype chain of a, the expression a instanceof A returns true. This means that we can trick instanceof into invalidating it.


var A = function() {}
 
var a = new A();
a.__proto__ == A.prototype; //true - so instanceof A will return true
a instanceof A; //true;
 
//mess around with a's prototype
a.__proto__ = Function.prototype;
 
//a's prototype no longer in same prototype chain as A's prototype property
a instanceof A; //false


So what else can I do with the prototype?

Remember I said that every constructor has an prototype attribute that can be used to assign a stereotype to all instances generated by the constructor? The same applies to local constructors, such as Function and String. By extending this property, rather than replacing it, we can update prototype for each object of the specified type.


//(works in IE<=8 too, due to double-negative)
false.__proto__ === Boolean(false).__proto__; //true
0

Tell me more about how inheritance and prototyping work. What is the prototype chain?


Since each object and each prototype (itself) has a prototype, we can imagine that one object after another is connected to form a prototype chain starting at 1. The end of the prototype chain is always the prototype of the default object (object).


//(works in IE<=8 too, due to double-negative)
false.__proto__ === Boolean(false).__proto__; //true
1


The prototype inheritance mechanism is inherently and implicitly implemented. When object a wants to access the attribute foo, Javascript traverses the prototype chain of a (starting with a itself), checking for foo attributes that exist in each link of the prototype chain. The foo attribute is returned if found, otherwise the undefined value is returned.

What about direct assignment?

The prototype inheritance mechanism does not work well when assigning object properties directly. a.foo='bar' assigns the foo attribute of a directly. To assign a property to a stereotype object, you need to directly locate that property of the stereotype object.
So much for the javascript prototype. I think my understanding of prototype concept is quite accurate, but my opinion is not the final result by any means. Please feel free to tell me where I'm wrong or give me a different opinion.


Related articles: