How to Understand JavaScript prototype

Source: Internet
Author: User

The prototype of Javascript is always confusing. No matter how experienced experts or the author himself, he often shows limited understanding of this concept, I think this confusion has emerged when we first came into contact with prototypes. They are often related to new and constructor, especially the prototype property of functions ). In fact, prototype is a very simple concept. To better understand it, we should first remember this principle, that is, to forget the knowledge we have learned about construtor prototypes.
 
What is prototype?
 
A prototype is an object that can be used to inherit attributes.
 
Can any object be prototype?
 
Yes
 
Objects with the original type
 
All objects have a prototype by default. Because the prototype itself is also an object, each prototype itself has a prototype (with only one exception, the default object prototype is at the top of the prototype chain. More about the prototype chain will be introduced later)
 
Okay, let's try again. What is the object?
 
In javascript, an object is a set of unordered key-value pairs. If it is not a primary data type (undefined, null, boolean, number, or string), it is an object.
 
You said that each object has a prototype, but when I write ({}). prototype, I get a null. Are you right?
 
Forget everything you have learned about prototype attributes. It may be the root cause of your confusion about prototype. The real Prototype of an object is held by the [[Prototype] property inside the object. ECMA introduces the standard Object prototype accesser object. getPrototype (Object). So far, only Firefox and chrome have implemented this accesser. Except IE, other browsers support non-standard accessors _ proto __. if neither of them works, we need to find its prototype attribute from the object constructor. The following code shows how to obtain the object prototype.
Var a = {};
 
// Firefox 3.6 and Chrome 5
 
Object. getPrototypeOf (a); // [object Object]
 
// Firefox 3.6, Chrome 5 and Safari 4
 
A. _ proto __; // [object Object]
 
// All browsers
 
A. constructor. prototype; // [object Object]
Okay, everything works fine, but false is a primary data type, but false. _ proto _ returns a value.
 
When you try to obtain a prototype of the primary data type, it is forcibly converted into an object
 
// (Works in IE too, but only by accident)
 
False. _ proto _ = Boolean (false). _ proto __; // true
What should I do if I want to use a prototype in inheritance?
 
It doesn't make much sense to use the prototype only because of an instance. This is the same as directly adding attributes to this instance. If we have created an instance object, we want to inherit the functions of an existing object, such as Array. We can do this as follows (in a browser that supports _ proto)
// Unusual case and does not work in IE
Var a = {};
A. _ proto _ = Array. prototype;
A. length; // 0
------------------------------------
Note: In the above example, an object a is created first, and then the prototype of a is used to inherit the existing object of Array.
------------------------------------
 
The real charm of the prototype lies in the fact that multiple instances share a common prototype. Once defined, the attributes of a prototype object (Note: The object referenced by the prototype of an object) can be inherited by multiple instances that reference it (note: that is, the prototype of these instance objects points to this prototype object.) This operation is self-evident in terms of performance and maintenance.
 
Is this the reason for the existence of Constructors?
 
Yes. Constructor provides a convenient cross-browser mechanism that allows you to provide a general prototype for an instance when creating an instance.
 
Before providing an example, I need to know what the constructor. prototype attribute is?
 
First, javascript does not distinguish constructor from other functions. Therefore, each function has a prototype attribute. In turn, if it is not a function, there will be no such attribute. See the following code.
 
// Function will never be a constructor but it has a prototype property anyway
 
Math. max. prototype; // [object Object]
 
// Function intended to be a constructor has a prototype too
 
Var A = function (name ){
 
This. name = name;
 
}
 
A. prototype; // [object Object]
 
// Math is not a function so no prototype property
 
Math. prototype; // null
Now we can define the prototype property of function A as an object. When this function is used as A constructor to create an instance, the prototype attribute of the function will be assigned to all object instances as the prototype (Note: The prototype attribute of all instances references the prototype attribute of the function)
------------------------------------
Note: The following Code gives a more detailed description of all this.
 
// Create a function B
Var B = function () {var one ;}
// Use B to create an object instance c
Var c = new B ();
// View constructor B and c
B. constructor; // function Function () {[native code]}
B. constructor = Function. constructor; // true
C. constructor; // constructor of instance c, that is, B function () {var one ;}
C. constructor = B // true
// B is a function. view the prototype of B as follows:
B. constructor. prototype // function (){}
B. _ proto _ // function (){}
 
// B is a function. Because javascript is not differentiated between constructor and function, functions are like constructor,
// There is a prototype attribute, which is different from the function prototype (B. _ proto _ or B. construtor. prototype ).
B. prototype // [object Object] prototype attribute of function B
 
B. prototype = B. constructor. prototype // fasle
B. prototype = B. _ proto _/false
B. _ proto __= = B. constructor. prototype // true
 
// C is an object instance created by B. view the prototype of c as follows:
C. constructor. prototype // [object Object] This is the prototype of the object.
C. _ proto _ // [object Object] This is the prototype of the object.
 
C. constructor. prototype = B. constructor. prototype; // compare the prototype of c with that of B
C. constructor. prototype = B. prototype; // compare the prototype of true c with that of B.
 
// Add an attribute max for the prototype property of function B
B. prototype. max = 3
// Instance c also has an attribute max
C. max // 3
In the above example, the prototype property of object instance c is the same as that of function B. If the prototype property of object instance c is changed, the object instance c
The prototype will also change.
------------------------------------
Understanding the prototype property of a function is actually irrelevant to the prototype. It is very important for us to understand the prototype property of a function.
// (Example fails in IE)
 
Var A = function (name ){
 
This. name = name;
 
}
 
A. prototype = A. _ proto __; // false
 
A. _ proto _ = Function. prototype; // true-A's prototype is set to its constructor's prototype property
Here is an example.
 
You may have used javascript For hundreds of times. Now, when you see such code again, you may have different understandings.
 
 
 
// Constructor. <em> this </em> is returned as new object and its internal [[prototype] property will be set to the constructor's default prototype property
Var Circle = function (radius ){
This. radius = radius;
// Next line is implicit, added for authentication only
// This. _ proto _ = Circle. prototype;
}
// Augment Circle's default prototype property thereby augmenting the prototype of each generated instance
Circle. prototype. area = function (){
Return Math. PI * this. radius * this. radius;
}
// Create two instances of a circle and make each leverage the common prototype
Var a = new Circle (3), B = new Circle (4 );
A. area (). toFixed (2); // 28.27
B. area (). toFixed (2); // 50.27
Great. If I changed the constructor prototype, does it mean that the existing constructor instance will get the latest version of constructor?
 
Not necessarily. If the prototype attribute is modified, such a change will occur. After a is actually created, a. _ proto _ is A reference to a. prototype ,.
 
Var A = function (name ){
This. name = name;
}
Var a = new A ('alpha ');
A. name; // 'alpha'
A. prototype. x = 23;
A. x; // 23
----------------------------------
Note: like in the previous example, the prototype of instance object a (. _ proto _) is the prototype attribute of function A (. prototype), So if you modify the prototype attribute of,
 
Changes will affect the object instance A created by a in the following example. However, the prototype of function A is modified, but it is not reflected in instance A created by.
 
Var A = function (name)
{
This. name = name;
}
Var a = new A ('alpha ');
A. name; // 'alpha'
 
A. _ proto _. max = 19880716;
 
A. max // undefined
 
----------------------------------
 
However, if I replace the prototype attribute of A with a new object, the prototype of the Instance Object A. _ proto _ still references the prototype attribute of A when it was created.
 
Var A = function (name ){
This. name = name;
}
Var a = new A ('alpha ');
A. name; // 'alpha'
A. prototype = {x: 23 };
A. x; // null
--------------------------------------
Note: After an instance is created, the prototype attribute of the function is changed to the object to which the instance prototype directs.
 
However, this does not affect the prototype of the created instance.
---------------------------------------
 
What does a default prototype look like?
 
Var A = function (){};
A. prototype. constructor = A; // true
Var a = new ();
A. constructor = A; // true (a's constructor property inherited from it's prototype)
What is the relationship between instance of and prototype?
 
If the prototype of a belongs to the prototype chain of A, the expression a instance of A is set to true. This means we can play tricks on instance of so that it does not work.
Var A = function (){}
 
Var a = new ();
 
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
What else can we do with prototype?
 
Remember that every constructor I have mentioned has a prototype attribute, which is used to provide a prototype for each instance it creates. This also applies to original ecological constructors such as Function and String. By extending this attribute, we can extend all instances of the specified constructor.
I have used this technique in many previous articles to demonstrate function expansion. All the string instances in the tracer utility article have implemented the times method to replicate the specified number of strings.
String. prototype. times = function (count ){
Return count <1? '': New Array (count + 1). join (this );
}
 
"Hello! ". Times (3); //" hello! Hello! Hello! ";
 
"Please...". times (6); // "please ..."
Tell me how inheritance works through prototype. What is prototype chain?
 
Because each object and prototype has a prototype (Note: The prototype is also an object), the prototype of the object points to the parent of the object, and the parent prototype points to the parent of the parent, we support this kind of relation connected by prototype layer by layer as the prototype chain. The end of a chain is usually the default object prototype.
 
A. _ proto _ = B;
 
B. _ proto _ = c;
 
C. _ proto _ = {}; // default object
 
{}. _ Proto _. _ proto __; // null
The prototype Inheritance Mechanism occurs internally and implicitly. if you want to obtain the value of foo in the property of object a, javascript will find the existence of foo in the prototype chain. if it finds it, return the value of foo; otherwise, undefined will be returned.
 
What about value assignment?
 
Prototype inheritance is not a player. When the property value is set to a. foo = 'bar', a bar is directly set for the property foo of. To add an attribute to the prototype, You need to specify the prototype directly.
 
The above is what this article describes. I personally feel that I have a deep understanding of prototype concepts, but my point of view does not represent everything. If you have any omissions or objections, please let us know.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.