The magical prototype_javascript skill of JS object-oriented

Source: Internet
Author: User
Tags abs visibility

The prototype property of an object in JavaScript that returns a reference to the object type prototype. This is a rather awkward explanation, and to understand it, the concept of object type (type) and prototype (prototype) should be understood first.
1 What is prototype
The prototype property of an object in JavaScript that returns a reference to the object type prototype. This is a rather awkward explanation, and to understand it, the concept of object type (type) and prototype (prototype) should be understood first.
Before we say, an object's class and object instance (Instance) is a "create" relationship, so we think of "class" as a model of the object's characteristics, and the object is considered to be an embodiment of a class feature, or a class is a type of object (type). For example, in the previous example, the types of P1 and P2 are point, and in JavaScript, this can be verified by the instanceof operator:
P1 instanceof Point
P2 instanceof Point
However, point is not the only type of P1 and P2, because P1 and P2 are objects, so obejct is also their type, because object is a more generalized class than it is, so we say that there is a kind of derivation between the obejct, and then we know that, This kind of relation is called "inheritance", it is also a special case of the generalization relation between objects, and it is an indispensable basic relation in object oriented.
In the object-oriented domain, instances and types are not unique pairs of abstract relationships that can be described, and in JavaScript, another important abstract relationship is type and prototype (prototype). This relationship is a higher level of abstraction, which happens to form a three-layer chain with the abstract relationship between type and instance.
In real life, we often say that something is created with another thing as a prototype. These two things can be of the same type, or they can be of different types. Idiom "according to gourd painting ladle", the gourd here is the prototype, and the scoop is the type, with JavaScript prototype to say is "scoop." prototype = some gourd "or" scoop. Prototype= new Gourd ().
To understand the prototype in depth, we can study a design pattern of--prototype pattern, the core of which is to use the prototype instance to specify the type of object to create, and to create new objects by copying these prototypes. The prototype of JavaScript is similar to this way.
The details of prototype pattern can be referred to as "design mode" ("Designing Patterns") it is not the scope of this article.
Note that unlike the relationship between the type and the instance, the relationship between the stereotype and the type requires that a type can have only one prototype at a time (while an instance can obviously have multiple types at one time). For JavaScript, this restriction has two layers of meaning, the first is that each specific JavaScript type has and has only one prototype (prototype), which, by default, is an object (note that it is not the object type!). )。 Second, the type that this object belongs to must be a chain of types that satisfies the prototype relationship. For example, the type that P1 belongs to is point and object, and an object is the prototype of point. If there is an object that belongs to the type ClassA, CLASSB, CLASSC, and object, then the four classes must be satisfied to form a complete prototype chain.
Interestingly, JavaScript does not specify the type of stereotype of a type (which is a very awkward word), so it can be of any type, usually an object, so that the object-type-prototype (object) may form a ring-like structure, or some other interesting topology, These structures provide a variety of uses for JavaScript, some of which are ingenious and aesthetically pleasing. The following section focuses on the use of prototype.

2 Prototype Use Tips
Before you understand the prototype skills, first understand the characteristics of prototype. First, JavaScript provides a prototype attribute for each type (type), which points to an object, which becomes the "archetype" of this type, meaning that all objects created by this type have the characteristics of this prototype. In addition, the JavaScript object is dynamic, and the prototype is no exception, adding or decreasing attributes to the prototype will change this type of prototype, which will directly affect all objects created by the prototype, such as:

Copy Code code as follows:

<script>
function Point (x,y)
{
this.x = x;
This.y = y;
}
var p1 = new Point (1,2);
var P2 = new Point (3,4);
point.prototype.z = 0; Attributes are added to the prototype for point dynamically
alert (P1.Z);
alert (P2.Z); All objects created by the point type at the same time
</script>

If a property named A is added to the prototype of an object, and the object itself has a property named a with the same name, the property of the object itself "overrides" the prototype property when accessing the object's property A, but the prototype property does not disappear. When you delete the property A of the object itself with the delete operator, the object's prototype property is restored to visibility. With this feature, you can set default values for the properties of an object, such as:
Copy Code code as follows:

<script>
function point (x, y)
{
if (x) this.x = x;
if (y) this.y = y;
}
point.prototype.x = 0;
point.prototype.y = 0;
var p1 = new Point;
var P2 = new Point (1,2);
</script>

The above example sets the default value (0,0) for the point object by prototype, so the P1 value is (0,0) and the P2 value is (1,2), with the delete p2.x, delete p2.y; The value of P2 can be restored to (0,0). Here's a more interesting example:
Copy Code code as follows:

<script>
function ClassA ()
{
THIS.A = 100;
this.b = 200;
THIS.C = 300;

This.reset = function ()
{
For (var all in this)
{
Delete This[each];
}
}
}
Classa.prototype = new ClassA ();

var a = new ClassA ();
alert (A.A);
A.A *= 2;
A.B *= 2;
A.C *= 2;
alert (A.A);
alert (A.B);
alert (A.C);
A.reset (); Call the Reset method to restore A's value to its default value
alert (A.A);
alert (A.B);
alert (A.C);
</script>

You can also use prototype to set a read-only getter for the properties of an object, thus preventing it from being overwritten. Here is an example:
Copy Code code as follows:

<script>
function point (x, y)
{
if (x) this.x = x;
if (y) this.y = y;
}
point.prototype.x = 0;
point.prototype.y = 0;

function LineSegment (p1, p2)
{
Private members
var m_firstpoint = p1;
var m_lastpoint = p2;
var m_width = {
Valueof:function () {return Math.Abs (p1.x-p2.x)},
Tostring:function () {return Math.Abs (p1.x-p2.x)}
}
var m_height = {
Valueof:function () {return Math.Abs (P1.Y-P2.Y)},
Tostring:function () {return Math.Abs (P1.Y-P2.Y)}
}
Getter
This.getfirstpoint = function ()
{
return m_firstpoint;
}
This.getlastpoint = function ()
{
return m_lastpoint;
}

This.length = {
Valueof:function () {return math.sqrt (M_width*m_width + m_height*m_height)},
Tostring:function () {return math.sqrt (M_width*m_width + m_height*m_height)}
}
}
var p1 = new Point;
var P2 = new Point (2,3);
var line1 = new LineSegment (p1, p2);
var LP = Line1.getfirstpoint ();
lp.x = 100; Accidentally rewrote the LP's value, destroying the LP's original value and not being recoverable
Alert (Line1.getfirstpoint (). x);
alert (line1.length); Even Line1.lenght has changed.
</script>

Rewrite the This.getfirstpoint () as follows:
Copy Code code as follows:

This.getfirstpoint = function ()
{
function GETTER () {};
Getter.prototype = M_firstpoint;
return new GETTER ();
}

You can avoid this problem and ensure the M_firstpoint property is read-only.
Copy Code code as follows:

<script>
function point (x, y)
{
if (x) this.x = x;
if (y) this.y = y;
}
point.prototype.x = 0;
point.prototype.y = 0;

function LineSegment (p1, p2)
{
Private members
var m_firstpoint = p1;
var m_lastpoint = p2;
var m_width = {
Valueof:function () {return Math.Abs (p1.x-p2.x)},
Tostring:function () {return Math.Abs (p1.x-p2.x)}
}
var m_height = {
Valueof:function () {return Math.Abs (P1.Y-P2.Y)},
Tostring:function () {return Math.Abs (P1.Y-P2.Y)}
}
Getter
This.getfirstpoint = function ()
{
function GETTER () {};
Getter.prototype = M_firstpoint;
return new GETTER ();
}
This.getlastpoint = function ()
{
function GETTER () {};
Getter.prototype = m_LastPoint;
return new GETTER ();
}

This.length = {
Valueof:function () {return math.sqrt (M_width*m_width + m_height*m_height)},
Tostring:function () {return math.sqrt (M_width*m_width + m_height*m_height)}
}
}
var p1 = new Point;
var P2 = new Point (2,3);
var line1 = new LineSegment (p1, p2);
var LP = Line1.getfirstpoint ();
lp.x = 100; Accidentally rewrote the LP's value, but did not destroy the original value
Alert (Line1.getfirstpoint (). x);
alert (line1.length); Line1.lenght doesn't change.
</script>

In fact, you set an object as a prototype of a type, this is equivalent to creating a read-only copy of the object by instantiating it, and changing the copy at any time does not affect the original object, and changes to the original object affect the copy unless the changed attribute has been overwritten with the copy's own attribute of the same name. You can restore the visibility of a prototype property by deleting the object's own name with the delete operation. Let me give you an example:
Copy Code code as follows:

<script>
function Polygon ()
{
var m_points = [];

m_points = array.apply (m_points, arguments);

function GETTER () {};
Getter.prototype = M_points[0];
This.firstpoint = new GETTER ();

This.length = {
Valueof:function () {return m_points.length},
Tostring:function () {return m_points.length}
}

This.add = function () {
M_points.push.apply (m_points, arguments);
}

This.getpoint = function (idx)
{
return M_POINTS[IDX];
}

This.setpoint = function (idx, point)
{
if (m_points[idx] = = null)
{
M_POINTS[IDX] = point;
}
Else
{
m_points[idx].x = Point.x;
M_points[idx].y = Point.y;
}
}
}
var p = new Polygon ({x:1, y:2},{x:2, Y:4},{x:2, y:6});
alert (p.length);
alert (p.firstpoint.x);
alert (P.FIRSTPOINT.Y);
P.firstpoint.x = 100; Accidentally wrote the value of it
Alert (p.getpoint (0). x); Does not affect the actual private member
Delete p.firstpoint.x; Recovery
alert (p.firstpoint.x);

P.setpoint (0, {x:3,y:4}); The actual private member is rewritten through the setter
alert (p.firstpoint.x); The value of the getter has changed
Alert (p.getpoint (0). x);
</script>

Note that the above example illustrates the use of prototype to quickly create multiple copies of an object, and generally, using prototype to create a large number of complex objects is much faster than copying objects in any other way. Note that using an object as a prototype to create a large number of new objects is precisely the essence of prototype pattern.
Here is an example:
Copy Code code as follows:

<script>
var p1 = new Point (1,2);
var points = [];
var pointprototype = function () {};
Pointprototype.prototype = p1;
for (var i = 0; i < 10000; i++)
{
Points[i] = new Pointprototype ();
Because the Pointprototype constructor is an empty function, it is constructed much faster than a direct constructed//P1 copy.
}
</script>

In addition to the above mentioned techniques, prototype, for its unique characteristics and other uses, is used as the broadest and most widely known possibility to simulate inheritance, and this is left to be discussed in the next section.
3 The essence of prototype
It has already said the role of prototype, and now we are going to reveal the essence of prototype by law.
We say that prototype behaves like a static domain in C + +, adding a property as a prototype property that will be shared by all instances created by that type, but this share is read-only. In any instance, you can only overwrite this property with your own attribute with the same name, not change it. In other words, when an object reads a property, it always checks the property sheet of its own field, and if it does, it returns the property, otherwise it reads the prototype field and returns the properties on the Protoype field. In addition, JavaScript allows the protoype domain to reference any type of object, so if the property is still not found on the Protoype field, JavaScript will recursively find the prototype domain of the object that the prototype domain is pointing to. Until the prototype field of this object is itself or the loop is present, we can use the following diagram to describe the relationship between prototype and the object instance:
Todo:
the value and limitation of 4 prototype
From the above analysis we understand the prototype, through it can be an object as a prototype, security to create a large number of instances, which is the real meaning of prototype, but also its value. As we'll see later, this feature of prototype can be used to simulate the inheritance of objects, but it's important to know that prototype is used to simulate inheritance, though it's an essential value, but it's definitely not the core of it, in other words, JavaScript's support for prototype is not simply a way to implement its object inheritance, and even without prototype inheritance, the prototype mechanism of JavaScript is still very useful.
Because prototype only builds replicas of types with objects, it also has a lot of limitations. First, it does not represent a copy of a value in the prototype domain of a type, but rather a reference copy, which brings "side effects". Changing the attribute value of a reference type on a prototype (another rather awkward explanation: P) will completely affect each instance of the type creation. Sometimes this is exactly what we need (such as the default values for all objects of a certain class), but sometimes this is something we don't want (like when the class inherits), here's an example:
Copy Code code as follows:

<script>
function ClassA ()
{
This.a=[];
}
function ClassB ()
{
This.b=function () {};
}
Classb.prototype=new ClassA ();
var objb1=new classb ();
var objb2=new classb ();
Objb1.a.push (1,2,3);
alert (objb2.a);
A member of all B's instances has changed!! This is not what this example wants to see.
</script>

JavaScript implementation:
Objects are inherited from Java.lang.Object in the Java language, and Java.lang.Object provides a way to clone, which means that if you implement an interface cloneable, you can support clone or throw an exception. At this point JavaScript is very close, all objects are inherited from object, but object does not support the method of cloning, but we can implement the Clone method by Expanddo the form of JavaScript. This enables all object creation in the future to implement the Clone method.
Because JavaScript itself does not provide a method of cloning, and for an assignment of an object such as Var A=new object (), var b=a, such code a,b point to the same object, the creation of an object must be implemented by the new keyword. So in the implementation of the clone, I have defined a constructor (constructor) Clonemodel internally, specifying that its parent object is the object for the clone activity itself, and therefore uses the This keyword, Based on our defined constructor Clonemodel, we create an object because there is no code inside the constructor, and the newly created object actually says that all implementations are in the parent object, which is the object we need to clone. So far, we've created an object that needs to be replicated, but all of the values point to the parent object.
In JavaScript's object-oriented approach, we have discussed that if the parent object's value is not overridden, then this time is directed directly to the parent object, and in prototype pattern, the intrinsic value of the object after the clone is required should not be related, and as long as the assignment is once, The value of the Objclone will be in its own memory space, not the parent object. Based on such considerations, OBJCLONE[V]=OBJCLONE[V] is a statement that implements the copy of the parent object's value through overwriting to its own memory.

21.2.1 What is prototype
The prototype property of an object in JavaScript that returns a reference to the object type prototype. This is a rather awkward explanation, and to understand it, the concept of object type (type) and prototype (prototype) should be understood first. Before we say, an object's class and object instance (Instance) is a "create" relationship, so we think of "class" as a model of the object's characteristics, and the object is considered to be an embodiment of a class feature, or a class is a type of object (type). For example, in the previous example, the types of P1 and P2 are point, and in JavaScript, this can be verified by the instanceof operator: P1 the instanceof point P2 instanceof Point but, point is not p The unique types of 1 and P2, because P1 and P2 are objects, so the obejct is also their type, because object is a more generalized class than point, so we say that there is a derivative relationship between the obejct, and we will know later that the relationship is called "Inheritance", It is also a special case of the generalization relation between objects, and it is an indispensable basic relation in the object-oriented. In the object-oriented domain, instances and types are not unique pairs of abstract relationships that can be described, and in JavaScript, another important abstract relationship is type and prototype (prototype). This relationship is a higher level of abstraction, and it happens to form a three-layer chain of abstract relationships between types and instances,

Figure 21.2 depicts this relationship:
Fig. 21.2 relationship between object, type and prototype
In real life, we often say that something is created with another thing as a prototype. These two things can be of the same type, or they can be of different types. Idioms "Suit", where the cat is a prototype, and the tiger is the type, with JavaScript prototype to say is "tiger prototype = a cat" or "Tiger prototype= new Cat." "Archetype" is one of the "classification" relationships between things in nature, and several other relationships include "inheritance" and "interface". In general, "inheritance" describes the inherent derivative relationships between things and can be strongly correlated (by descent) between things described by "inheritance". "Interface" describes the common features of the function of things. and "archetype" tends to describe the "similarity" between things. From this point of view, "prototype" in terms of describing the relevance of things, than inheritance and interface more broadly. If you are a Java programmer, the example above is considered from the perspective of inheritance, of course, the "cat" to Inherit the "Tiger", and can not use the "tiger" to inherit the "cat", to describe their relationship, need to build a cover their common "abstract class", or you will call it "cat animals." However, if my system only needs "cat" and "Tiger", then this superfluous "cat" for me does not make any sense, I just need to say, "Tiger" is a bit like "cat", that's all. Here, using prototypes to help us successfully save a type of "feline" that is not necessary to build. To understand the prototype in depth, we can study a design pattern of--prototype pattern, the core of which is to use the prototype instance to specify the type of object to create, and to create new objects by copying these prototypes. The prototype of JavaScript is similar to this way. The details of prototype pattern can be referred to as "design mode" ("Designing Patterns") it is not the scope of this book discussion. Note that the prototype pattern requires a type to have only one prototype at a time (while an instance can obviously have multiple types at one time). For JavaScript, this restriction has two layers of meaning, the first is that each specific JavaScript type has and has only one prototype (prototype), which, by default, is an object (note that it is not the object type!). )。 The second is that all types of instances of this type must be chain of types that satisfy the prototype relationship. For example, the type that P1 belongs to is point and object, and an object is the prototype of point. If there is an object, it belongs to the type ClassA, CLASSB, CLASSC, and OBJ, respectively.ECT, then the four classes must be met to form a complete prototype chain, for example:
The type chain of the prototype relationship in example 21.4
function ClassA ()
{
......
}
Classa.prototype = new Object (); This can be omitted.
function ClassB ()
{
......
}
Classb.prototype = new ClassA (); CLASSB is based on the ClassA object
function CLASSC ()
{
......
}
Classc.prototype = new ClassB (); CLASSC is based on the ClassB object
var obj = new CLASSC ();
Alert (obj instanceof CLASSC); True
Alert (obj instanceof CLASSB); True
Alert (obj instanceof ClassA); True
Alert (obj instanceof Object); True

Figure 21.3 briefly describes the relationship between them:
Fig. 21.3 The type chain of the prototype relationship
The interesting thing is that JavaScript does not specify the type of prototype of a type (which is a very awkward word), so it can be of any type, usually an object, so that object-type-prototype (object) may form a ring structure, or other interesting topological structures, which are JavaScript brings a myriad of uses, some of which are ingenious and aesthetically pleasing. The following section focuses on the use of prototype. <

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.