Analysis of Principles and Examples of javascript prototype, prototype chain, and object replication (II)
Prototype
Prototype is an important concept in JavaScript object-oriented features and is also a concept that everyone is too familiar. Because in most cases
In the object-oriented language of data, objects are class-based (such as Java and C ++), and objects are the results of class instantiation. In
There is no class concept in JavaScript.
① Objects are instantiated by objects. For example, classes in a class-based language
Like a mold, an object is produced by casting the mold, and in a prototype-based language, the prototype is like a work of art.
We can copy the original from a machine with a precision of 100%.
The prototype is not involved in the examples in the previous section. You can generate classes by using constructors and new statements.
See how to use the prototype and constructor to generate objects together.
Function Person (){}
Person. prototype. name = 'byvoid ';
Person. prototype. showName = function (){
Console. log (this. name );
};
Var person = new Person ();
Person. showName ();
The above Code uses a prototype instead of a constructor to initialize an object. This is done and is directly defined in the constructor.
What are the differences between attributes?
**The property inheritance method defined in the constructor is different from that defined in the prototype. The sub-object must explicitly call the parent object to inherit the structure.
Attributes defined in the function.
Any attribute defined in the constructor, including the function, will be repeatedly created.
The two objects do not share the instance.**
The function defined in the constructor has the overhead of the runtime closure, because the local variables in the constructor define
The function is also visible.
The following code verifies the above problems:
Function Foo (){
Var innerVar = 'hello ';
This. prop1 = 'byvoid ';
This. func1 = function (){
InnerVar = ";
};
}
Foo. prototype. prop2 = 'carbo ';
Foo. prototype. func2 = function (){
Console. log (this. prop2 );
};
Var foo1 = new Foo ();
Var foo2 = new Foo ();
Console. log (foo1.func1 = foo2.func1); // output false
Console. log (foo1.func2 = foo2.func2); // Output true
However, it does not mean that the attribute creation in the constructor is not good, but that the two have their own appropriate scopes. Then we
When will a prototype be used, and when will an attribute be created using the definition in the constructor?
** Unless you must use a constructor closure, use a prototype to define a member function as much as possible, which reduces overhead.
Define general members in the constructor, especially objects or arrays, because the prototype defines multiple members.
Shared by the instance. **
Next, we will introduce the prototype chain mechanism in JavaScript.
Prototype chain
JavaScript has two special objects: Object and Function. They are constructors used to generate
Object. Object. prototype is the ancestor of all objects, and Function. prototype is the original
Type, including constructor. I divide JavaScript objects into three types,
One is the object created by the user,
The first type is the constructor object,
The first type is the prototype object.
An object created by a user, that is, an object explicitly constructed using the new statement.
A constructor object refers to a common constructor, that is, a function that generates a common object through a new call.
The prototype object refers to the object pointed to by the prototype attribute of the constructor.
Each of these three types of objects hasProtoProperty, which points to the prototype of the Object. Any Object that traverses along it can be traced back to Object. prototype.
The constructor object has the prototype attribute and points to a prototype object. when an object is created through this constructorProtoThe property will point to the prototype attribute of the constructor.
The prototype object has the constructor attribute and points to its corresponding constructor. Let's use the following example to understand the prototype:
Function Foo (){}
Object. prototype. name = 'my object ';
Foo. prototype. name = 'bar ';
Var obj = new Object ();
Var foo = new Foo ();
Console. log (obj. name); // output My Object
Console. log (foo. name); // output Bar
Console. log (foo.Proto. Name); // output Bar
Console. log (foo.Proto.Proto. Name); // output My Object
Console. log (foo.Proto. Constructor. prototype. name); // output Bar
We define a constructor called Foo () and generate the object foo. At the same time, we also generate prototype objects for the Object and Foo respectively.
Parses the intricate relationships between them.
Object Replication
JavaScript and Java do not have the same pointer as the C language. All object-type variables point
When two variables are assigned a value, an object is not copied, but a reference is passed.
Sometimes we need to completely copy an object. What should we do?Java supports the clone method.
Current object replication, but JavaScript does not have such a function. Therefore, we need to manually implement such a function,
A simple method is to copy all attributes of an object: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> Expires + DQp9PGJyIC8 + expires + yc/expires/PHs7 + expires/expires + expires/zubLP7bbUz/expires + expires/ytcTKx82s0ru49sr91 + authorization + yN3S17XEysKjrNLyzqqz/cHLu/mxvsr9vt08yniglz4ncsd1_m2jrlu509c24nbwsrvnrlxetttp86ostttp88tasr + authorization = "| typeof (this [I] = 'function '){
NewObj [I] = this [I]. clone ();
} Else {
NewObj [I] = this [I];
}
}
Return newObj;
};
Array. prototype. clone = function (){
Var newArray = [];
For (var I = 0; I <this. length; I ++ ){
If (typeof (this [I]) = 'object' | typeof (this [I]) = 'function '){
NewArray [I] = this [I]. clone ();
} Else {
NewArray [I] = this [I];
}
}
Return newArray;
};
Function. prototype. clone = function (){
Var that = this;
Var newFunc = function (){
Return that. apply (this, arguments );
};
For (var I in this ){
NewFunc [I] = this [I];
}
Return newFunc;
};
Var obj = {
Name: 'byvoid ',
Likes: ['node'],
Display: function (){
Console. log (this. name );
},
};
Var newObj = obj. clone ();
NewObj. likes. push ('python ');
Console. log (obj. likes); // output ['node']
Console. log (newObj. likes); // output ['node', 'python']
Console. log (newObj. display = obj. display); // output false
The above implementation looks perfect. It not only Recursively copies the complex structure of the object, but also implements the depth of the Function
Copy. This method is useful in most cases, but in one case it is powerless, such as the following code:
Var obj1 = {
Ref: null
};
Var obj2 = {
Ref: obj1
};
Obj1.ref = obj2;
The logic of this code is very simple, that is, two referenced objects. When we try to use deep copy to copy
When any one of obj1 and obj2 occurs, the problem arises. Because the method of deep copy is recursion when an object is encountered.
The results can only be infinitely replicated. In this case, simple recursion cannot be solved, so we must design
Set ** Graph Theory Algorithms to analyze the dependencies between objects, create a topology, and copy each vertex in sequence,
And re-build the dependency between them **.