[TranslationArticleFrom: http://www.yuiblog.com/blog/2010/01/06/inheritance-patterns-in-yui-3/]
This article discusses two types of JavaScript implemented in Yui 3.CodeReuse mode-classical inheritance pattern and Prototypal inheritance pattern ).
Required dependencies (satisfied dependences)
Prototype inheritance mode is implemented as the core API of Yui 3 in the "yui-min.js" seed file. The type inheritance mode requires the "Oop" module. However, the "Oop" module is used by many other modules. Generally, you do not need to make additional references to use this function. If you want to create a simple test page to try this mode, you can reference the required modules as follows:
<Br/> <MCE: Script Type = "text/JavaScript" src = "http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js" mce_src = "http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"> </MCE: SCRIPT> <br/> <MCE: script Type = "text/JavaScript"> <! -- <Br/> Yui (). use ('oop ', function (y) {<br/> // your code goes here <br/> // y is the Yui instance <br/> }); <br/> // --> </MCE: SCRIPT> <br/>
Classical inheritance pattern)
We call the type inheritance pattern "classical" not because it comes from the Plato age of ancient Egypt, but because it can help you think about problems in the "type" way. Javascript has no type. Instead, JavaScript has constructor ). For example, in Java or other languages, you can define the "programmer" type and make it inherit the "person" type. However, what you can directly define in Javascript is a programmer constructor and a person constructor. The object created by the programmer constructor can inherit the properties and methods created by the person constructor ).
Consider the following two constructors:
<Br/> // parent <br/> function person () {<br/> // "own" members <br/> This. name = "Adam"; <br/>}</P> <p> // properties of the parent's prototype <br/> person. prototype. getname = function () {return this. name ;}; </P> <p> // child constructor <br/> function Programmer () {}< br/>
In Yui 3, the "Y. Extend (…) provided by the" Oop "module (...) "The method allows you to easily implement the type inheritance mode:
<Br/> Y. Extend (programmer, person); <br/>
Now you can test whether the "getname ()" method is inherited correctly as follows:
<Br/> var guru = new Programmer (); <br/> alert (typeof guru. getname); // "function" </P> <p>
Note: "Y. Extend (...) "Methods inherit only the Members in prototype, not the private members (" own "members ). Therefore, a good habit is to add all reusable functions to prototype, and define all attributes related to type instances as private properties ("own" properties ). As in the above example, "getname ()" is inherited to programmer, while "name" is not inherited (in the prototype inheritance mode to be discussed later, "prototype" and "own" members are inherited ).
Extend and augment)
"Y. Extend (...) "Functions not only allow you to inherit the parent constructor, but also add new members to the subclass. Yui is actually the "de facto" mode to extend classes. You can use "Y. Extend (...) "The third parameter of the function adds attributes to the prototype of the subclass, and you can use its fourth parameter to add its own static properties to the subclass ). The following is an example of expansion and enhancement:
<Br/> Y. extend (programmer, person, {grokshtml: true}, {limit: "sky "}); </P> <p> // grokshtml is now a property of the child's prototype <br/> alert (typeof programmer. prototype. grokshtml); // "Boolean" </P> <p> // The property works for all new objects <br/> var Bob = new Programmer (); <br/> alert (Bob. grokshtml ); // true </P> <p> // adding to the constructor is more for <br/> // "static" properties meant to act as constants <br/> alert (programmer. limit); // "sky" <br/> var Limit = Bob. limit; // undefined <br/>
Parent class)
The type inheritance mode of yui3 also provides a static property-superclass-allowing you to access the prototype of the parent class constructor. Because "supperclass" points to the prototype of the parent class constructor, "superclass. custructor" points to the constructor of the parent class. For example:
<Br/> // inherit <br/> Y. extend (programmer, person); </P> <p> // child's access to the parent constructor <br/> var parent = programmer. superclass. constructor; </P> <p> // test <br/> alert (parent = person ); // true </P> <p> // access to the parent from an instance of the Child <br/> var guru = new Programmer (); <br/> guru. constructor. superclass. constructor === person; // true <br/>
As mentioned above, the classic inheritance mode can only inherit prototype members. However, by using "superclass", you can call the constructor of the parent class in the subclass. In this way, you can change the private property (own properties) of the parent class to the private property (own properties) of the subclass ). For example, you can call the parent class constructor In the programmer constructor to pass in the subclass instance (this) and any initialization parameters:
<Br/> // child <br/> function Programmer () {<br/> // initialize the parent using the child as "this" <br/> programmer. superclass. constructor. apply (this, arguments); <br/>}</P> <p> // inheritance <br/> Y. extend (programmer, person); <br/> // test <br/> var pro = new Programmer (); <br/> alert (Pro. name); // "Adam" </P> <p>
As you can see, the "programmer" instance now has the "name" attribute, and it is a private property (own property ):
<Br/> alert (Pro. hasownproperty ('name'); // true <br/> alert (Pro. hasownproperty ('getname'); // false. it is public property, not own property. <br/>
Access to overridden Methods)
Because "superclass" points to the prototype of the parent class constructor, this provides us with a way to access the reset method. Consider the following typical example (Triangle inherits from shape ):
<Br/> // parent <br/> function shape () {}< br/> shape. prototype. tostring = function () {<br/> return "shape"; <br/>}; </P> <p> // child <br/> function triangle () {}</P> <p> // inheritance <br/> Y. extend (triangle, shape); </P> <p> // child overrides the parent's tostring () method <br/> // but thanks to the superclass property <br/> // it still has access to the original method <br/> triangle. prototype. tostring = function () {<br/> return triangle. superclass. tostring () + ", triangle"; <br/>}; </P> <p> // test <br/> var acute = New Triangle (); <br/> acute. tostring (); "shape, triangle" <br/>
Prototypal inheritance pattern)
Douglas crockford recommends this inheritance mode. This mode removes the concept of all types, allowing you to directly inherit from one instance to another. For example:
<Br/> // parent object, created with a simple object literal <br/> var parent ={< br/> name: "John", <br/> family: "Wayne", <br/> say: function () {<br/> return "I am" + this. name + "" + this. family; <br/>}< br/> }; </P> <p> // The Inheritance magic <br/> // a new object is born from an existing one <br/> var Batman = y. object (parent); </P> <p> // customize or augment the new object <br/> Batman. name = "Bruce"; </P> <p> // use <br/> Batman. say (); // I am Bruce Wayne <br/>
You can use this mode in the following two steps:
- Create a new object that inherits all attributes and methods of an existing object.
- Customize is a new object. You can overwrite inherited members or add new members.
Note: "Y. Object (...) "Included in Yui core library. You do not need to apply the "Oop" module
Prototype inheritance
If you are interested in the motives behind the prototype inheritance mode and the underlying implementation mechanism, you can refer to Douglas crockford's own description of this mode. When this mode is used, the members of the parent class inherit from the "prototype" chain. This means that if the subclass adds an attribute with the same name as the parent class, the subclass property will not overwrite the property inherited from the parent class, but it will have priority access. In other words, you can redefine the "say" method in the above example as follows:
<Br/> Batman. say = function () {<br/> return "can't tell you my real name"; <br/> }; </P> <p> // test <br/> Batman. say (); // "can't tell you my real name" <br/>
And y. Extend (...) The type inheritance modes provided by the function are different. The prototype inheritance mode cannot provide the "say" method similar to the "superclass" attribute to access the parent class. However, if you delete the "say" method of the (delete) subclass, the method of the parent class will be exposed. As follows:
<Br/> Delete Batman. Say; <br/> Batman. Say (); // "I am Bruce Wayne" <br/>
In the latest version of ecmascript, it provides an native method "object. Create (...) "To support the prototype inheritance mode:
<Br/> // yui3 <br/> var Batman = y. object (parent); </P> <p> // ecmascript 5 (future) <br/> var Batman = object. create (parent); <br/>
More resources
Thank you for reading! For more information and examples of these two modes, refer to the following link:
Del. icio. US : Yui 3, code reuse mode, inheritance mode