Prototype vs Class Inheritance in YUI 3

0

Posted on : 01/07/2010 | By : Jimmy Vu | In : Development News, Solution

As I mentioned in the post YUI 3.0 – Changes From the Root, YUI 3 is a radical evolvement of the framework. One of the most interesting features it provides with is about much better support for OOP.

YUI 3 supports two inheritance patterns via object prototype and “class”. Let’s examine the differences and advantages of each pattern.

Prototypal Inheritance in YUI 3

Suggested by Douglas Crockford, prototypal inheritance pattern is to deal with objects, i.e. objects inherit from objects. YUI 3 supports prototypal inheritance from its core; it means you can utilize the pattern by including the seed file only:

<script type="text/javascript" 
    src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"></script>

Now, for example, we have an object named animal:

var animal = {
    name: "Animal",
    level: "top",
    say: function() {
        return "I am an " + this.name + " at " + this.level + " level.";
    }
};
 
alert(animal.say()); // I am an Animal at top level.

And you want to create an elephant object that is an inheritance of animal. It’s so easy to do:

var elephant = Y.Object(animal);

Of course, you’ll need to modify the newly-born creature to make it a true elephant by overriding its parent properties and adding some new ones:

// override an animal’s property
elephant.level = "second";
 
// add elephant’s own properties
elephant.trunk = 1;
elephant.tusks = 2;

However if you want the elephant to say more about its own belongings, you’ll have to redefine say method completely.

elephant.say = function(){
    return "I am an " + this.name + " at " + this.level + " level."
        + " I have " + this.trunk + " trunk and " + this.tusks + " tusks.";
};
 
alert(elephant.say()); // I am an Animal at second level. I have 1 trunk and 2 tusks.

I think this pattern is quite easy to understand but before going forward to the next one, here are what we learn from it:

  1. We can create a new object that inherits all the properties and methods from an existing object.
  2. We can customize the new object by overwriting some/all of the members or adding new ones.
  3. The dark part is an overwritten property has no way to reference its parent’s property.

    Note: In this pattern, the child’s properties do not really overwrite its parent’s ones but they just take higher precedence. So if we delete a child’s method, the parent’s one will be back magically. For example:

    delete elephant.say;
    alert(elephant.say()); // I am an Animal at second level.

“Class” Inheritance in YUI 3

Yes, I know there are no true classes in JavaScript, however we can make constructor functions act like classes for OOP (you can read more from the book Object-Oriented JavaScript by Stoyan Stefanov).

Note: From now on, for easier to understand the pattern, I’ll call all constructor functions (that are capitalized in examples) classes; don’t be confused.

First, we’ll mimic above example by creating  Animal and Elephant classes as follows:

// parent class
function Animal(){
    this.name = "Animal";	
}
// parent’s properties
Animal.prototype.getName = function(){
    return this.name;
};
Animal.prototype.setName = function(name){
    this.name = name;
};
 
// child class
function Elephant(){}

YUI 3 supports class inheritance via oop module and because this is used widely by almost all other modules, you’ll rarely have to include it explicitly. However, for testing, just call Y.extend() method within oop’s scope (that let Elephant inherit Animal as you can guess):

YUI().use('oop', function(Y){
    Y.extend(Elephant, Animal);
 
    // test code here
    // ...
}

Next we’ll do some tests:

// create an object of Elephant
var jumbo = new Elephant();
 
alert(typeof(jumbo.name)); // undefined
alert(typeof(jumbo.getName)); // function
 
// set name for the Elephant object			
jumbo.setName("Jumbo");
alert(jumbo.getName()); // Jumbo

You can see from the example, jumbo object which is an instance of Elephant class only inherit members of the prototype, not “private” members from parent’s class and it is considered a good practice to leave all instance-specific properties as private properties and to add all the public functionality to the prototype.

Interestingly we can add some new properties with default values to child class via arguments of Y.extend(), for example, to add trunk and tusks to Elephant class:

// create an object of Elephant “class”
var jumbo = new Elephant();
 
alert(typeof(jumbo.name)); // undefined
alert(typeof(jumbo.getName)); // function
 
// set name for the elephant				
jumbo.setName("Jumbo");
alert(jumbo.getName()); // Jumbo

Last but not least, class inheritance has very powerful feature: superclass access. To see how it works, we’ll add a method to Animal class to let it say something.

// parent class
function Animal(){}
 
// parent’s method
Animal.prototype.say = function(){
    return "I am an animal.";
};

Then, we’ll overwrite say method in Elephant class, yet still be able to keep what Animal can say about.

Y.extend(Elephant, Animal, {trunk: 1, tusks: 2});
 
Elephant.prototype.say = function(){
    	  return Elephant.superclass.say() + 
		" I have " + this.trunk + " trunk and " + this.tusks + " tusks.";
};
 
// test
jumbo = new Elephant();
alert(jumbo.say()); // I am an animal. I have 1 trunk and 2 tusks.

In summary, “class” inheritance pattern in YUI 3 is more powerful than prototypal counterpart though harder to get it full, here are some important points:

  1. YUI 3 allows us to implement inheritance at (pseudo) class level in JavaScript.
  2. Inherited classes cannot directly access to parent’s own members, children only inherit prototype members by default.

    Note: Well, it is possible to inherit parent’s own properties by initializing the parent constructor from the child (but it is not always a good OOP practice). See example:

    // parent class
    function Animal(){
        this.name = "Animal";	
    }
    // child class
    function Elephant() {
        // initialize the parent using the child as "this"
        Elephant.superclass.constructor.apply(this, arguments);
    }
     
    Y.extend(Elephant, Animal);
     
    // test
    jumbo = new Elephant();
    alert(jumbo.name); // Animal
  3. You can gain access to the parent’s overridden methods via superclass.

Conclusion

Code reuse is considered as the most confusing part of JavaScript for it lacks robust OOP features that many modern programming languages provide by default. YUI 3 with the two inheritance patterns we’ve gone through is trying to fill the gap.

Prototypal inheritance is easier to understand but limit in object inheritance only. To get full OO support in YUI 3, it is advisable to study “class” inheritance pattern provided by the framework.

Recommended Reading

High Performance JavaScript (Build Faster Web Application Interfaces)High Performance JavaScript (Build Faster Web Application Interfaces)

If you're like most developers, you rely heavily on JavaScript to build interactive and quick-responding web applications. The problem is that all ... Read More >

Pro JavaScript Design Patterns (Recipes: a Problem-Solution Ap)Pro JavaScript Design Patterns (Recipes: a Problem-Solution Ap)

JavaScript is a hugely popular language for adding dynamic functionality to web pages, and it is possible to use design patterns within JavaScript ... Read More >

JavaScript: The Definitive Guide: Activate Your Web Pages (Definitive Guides)JavaScript: The Definitive Guide: Activate Your Web Pages (Definitive Guides)

Since 1996, JavaScript: The Definitive Guide has been the bible for JavaScript programmers—a programmer's guide and comprehensive reference to th... Read More >

YUI 3.0 – Changes From the Root

1

Posted on : 08/28/2008 | By : Jimmy Vu | In : Development News

If you are web developer you may have noticed that the latest version of Yahoo’s User Interface toolset and widgets (for web development), YUI 3.0, is now available as a preview release. YUI has long been a popular “Ajax” library both because of its liberal BSD license, and because of the number of features it provides.

The big news about YUI the third are that it changes from the root and (unfortunately) is not compatible with YUI 2.x APIs as Eric and Matt stated on developer blog.

YUI 3.0 builds off of the YUI 2.x codeline, but we’ve evolved most of the core APIs in working toward the five key goals described above. As a result, migrating from YUI 2.x to 3.x will require effort at the implementation level.

However, YUI 3.0 will ship with a limited compatibility layer for the current YUI Core that will allow you to run some of your YUI 2.x-based implementations (Yahoo Global Object, Dom Collection, and Event Utility) on top of YUI 3.0.

These radical changes are toward 5 goals:

  • Lighter (less K-weight on the wire and on the page for most uses)
  • faster (fewer http requests, less code to write and compile, more efficient code)
  • more consistent (common naming, event signatures, and widget APIs throughout the library)
  • more powerful (do more with less implementation code)
  • more securable (safer and easier to expose to multiple developers working in the same environment; easier to run under systems like Caja or ADsafe)

Read the rest of this entry »

Recommended Reading

Plan to redirect Academic Health funds slammed: reaction to IOM report.(Practice Trends): An article from: Family Practice NewsThis digital document is an article from Family Practice News, published by International Medical News Group on October 1, 2003. The length of the art... Read More >
Prempro 0.45/1.5. (New & Approved).: An article from: Family Practice NewsThis digital document is an article from Family Practice News, published by International Medical News Group on April 15, 2003. The length of the arti... Read More >
Oxytrol. (New & Approved).(Brief Article): An article from: Family Practice NewsThis digital document is an article from Family Practice News, published by International Medical News Group on April 15, 2003. The length of the arti... Read More >