Code reuse and its principles
<font face="NSimsun">代码复用</font>
, as the name suggests, is to reuse part or even all of the code that has been written before to build a new program. When talking about code reuse, the first thing we can think of is <font face="NSimsun">继承性</font>
. The principle of code reuse is:
<code>优先使用对象组合,而不是类继承</code>
In js, since there is no concept of class, the concept of instance does not make much sense. Objects in js are simple key-value pairs, and they can be created and modified dynamically.
But in <font face="NSimsun">js</font>
, we can use constructors and <font face="NSimsun">new</font>
operators to instantiate an object, which has syntax similarities with other programming languages that use classes.
For example:
<code>var trigkit4 = new Person();</code>
<font face="NSimsun">js</font>
seems to be a class when calling the constructor <font face="NSimsun">Person</font>
, but it is actually still a function. This gives us some development ideas and inheritance patterns that are assumed to be based on classes. We It can be called the "class inheritance pattern".
The traditional inheritance mode requires the <font face="NSimsun">class</font>
keyword. We assume that the above class inheritance mode is <font face="NSimsun">现代继承模式</font>
, which is a mode that does not need to be considered in terms of classes.
Class inheritance pattern
Look at the following examples of two constructors <font face="NSimsun">Parent()</font>
and <font face="NSimsun">Child()</font>
:
<code><script type="text/javascript"><br> function Parent(name){<br> this.name = name || 'Allen';<br> }<br> Parent.prototype.say = function(){<br> return this.name;<br> }<br> function Child(name){}<br> //用Parent构造函数创建一个对象,并将该对象赋值给Child原型以实现继承<br> function inherit(C,P){<br> C.prototype = new P();//原型属性应该指向一个对象,而不是函数<br> }<br> //调用声明的继承函数<br> inherit(Child,Parent);<br></script></code>
When you create an object using the <font face="NSimsun">new Child()</font>
statement, it gets its functionality from the <font face="NSimsun">Parent()</font>
instance through the prototype, such as:
<code>var kid = new Child(); kid.say(); //Allen</code>
Prototype Chain
Discuss how the prototype chain works in the class inheritance model. We think of an object as a block somewhere in memory. This memory block contains data and references to other blocks. When using the <font face="NSimsun">new Parent()</font>
statement to create an object, a block like the one on the left side of the figure below will be created. This block saves the <font face="NSimsun">name</font>
attributes. If we want to access the <font face="NSimsun">say()</font>
method, we can pass the <font face="NSimsun">Parent()</font> The implicit link <font face="NSimsun">prototype</font>
of the 🎜> (prototype) attribute can access the block on the right <font face="NSimsun">__proto__</font>
. <font face="NSimsun">Parent.prototype</font>
So, what happens when you use
to create a new object? As shown below: <font face="NSimsun">var kid = new Child()</font>
The object created using the
statement is almost empty except for the implicit link <font face="NSimsun">new Child()</font>
. In this case, <font face="NSimsun">__proto__</font>
points to the object <font face="NSimsun">__proto__</font>
created using the <font face="NSimsun">inherit()</font>
statement in the <font face="NSimsun">new Parent()</font>
function.
, since the block object in the lower left corner does not have a <font face="NSimsun">kid.say()</font>
method, it will query the middle block object through the prototype chain. However, the middle block object does not have a <font face="NSimsun">say()</font>
method either. method, so he followed the prototype chain to query the rightmost block object, and this object happened to have the <font face="NSimsun">say()</font>
method. Is it over? <font face="NSimsun">say()</font>
is referenced in the <font face="NSimsun">say()</font>
method. This points to the object created by the constructor. Here, it points to the <font face="NSimsun">this.name</font>
block. However, <font face="NSimsun">new Child()</font>
does not have the <font face="NSimsun">new Child()</font>
attribute. For this reason, the middle block will be queried, and the middle block happens to have the <font face="NSimsun">name</font>
attribute. At this point, the query of the prototype chain is completed. <font face="NSimsun">name</font>
Javascript Study Notes (5) Detailed Explanation of Prototype and Prototype Chain
Share prototypes
The rule of this pattern is: reusable members should be transferred to the prototype instead of placed in this. Therefore, for inheritance purposes, anything worth inheriting should be implemented in a prototype. Therefore, you can set the prototype of the child object to be the same as the prototype of the parent object, as shown in the following example:
<code>function inherit(C,P){<br> C.prototype = P.prototype;<br>}</code>
子对象和父对象共享同一个原型,并且可以同等的访问<font face="NSimsun">say()</font>
方法。然而,子对象并没有继承<font face="NSimsun">name</font>
属性
原型继承
原型继承是一种“现代”无类继承模式。看如下实例:
<code><script type="text/javascript"><br> //要继承的对象<br> var parent = {<br> name : "Jack" //这里不能有分号哦<br> };</code> <code> //新对象<br> var child = Object(parent);</code> <code> alert(child.name);//Jack<br></script></code>
在原型模式中,并不需要使用对象字面量来创建父对象。如下代码所示,可以使用构造函数来创建父对象,这样做的话,自身的属性和构造函数的原型的属性都将被继承。
<code><script type="text/javascript"><br> //父构造函数<br> function Person(){<br> this.name = "trigkit4";<br> }<br> //添加到原型的属性<br> Person.prototype.getName = function(){<br> return this.name;<br> };<br> //创建一个新的Person类对象<br> var obj = new Person();<br> //继承<br> var kid = Object(obj);<br> alert(kid.getName());//trigkit4<br></script></code>
本模式中,可以选择仅继承现有构造函数的原型对象。对象继承自对象,而不论父对象是如何创建的,如下实例:
<code><script type="text/javascript"><br> //父构造函数<br> function Person(){<br> this.name = "trigkit4";<br> }<br> //添加到原型的属性<br> Person.prototype.getName = function(){<br> return this.name;<br> };<br> //创建一个新的Person类对象<br> var obj = new Person();<br> //继承<br> var kid = Object(Person.prototype);<br> console.log(typeof kid.getName);//function,因为它在原型中<br> console.log(typeof kid.name);//undefined,因为只有该原型是继承的<br></script></code>