Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Tuesday, May 8, 2007

Prototype vs. YUI round 1: OOP Architecture

First, let’s make sure we are all using the same Frameworks, because these teams have been cranking out changes faster than you can keep up with them. This discussion will use the stable release of Prototype 1.5.1 and YUI 2.2.0. We will be analyzing the speed of creating small dummy objects to get an idea of which approach is better. Before, starting, I’d like to take a moment to thank the YUI guys for following rigorous coding standards and well documenting their code. I don’t know what high-horse the Prototype guys are riding, but there code is sloppy and it doesn’t compress well. Consequently, I have taken some time to clean up the prototype code (added semi colons, {} all statements, and ran jsmin): uncompressed and minified.

In the Prototype Framework you create Objects using the ‘Class.create()’ method. This basically attaches a function to your Object, that will execute the ‘initialize’ method you attach to the Object’s ‘prototype’ Object with all the variables you passed into the constructor. That’s a mouth full and a little hard to grasp textually, here is an example:

var PrototypeObject = Class.create();
PrototypeObject.prototype = {
initialize: function(v1, v2) {
// my initialization code
this.v1 = v1;
this.v2 = v2;
},
testFunction: function() {
alert(this.v1);
}
};
// to use
var someVariable = new PrototypeObject (v1, v2);
someVariable.testFunction();

The ’someVariable’ Object will contain all the functions and variables attached to ‘PrototypeObject.prototype’, including the initialize function. When I used this OOP Architecture, I often design the initialize function in such a way that it could be called again later to reset the object. This example illustrates how you can pass variables into the constructor and set them internally so that other function, like ‘testFunction’ can access the v1 variable, because it is attached to the ‘this’ keyword Object. You can extend these Object indefinitely, declare addition Objects inside, and do any number of customizations. However, I find that these Objects become larger than they need to be and are often difficult to follow.

In the YUI Framework you create Objects by executing a Function that contains ‘private’ like variables accessible only in the scope of the Function or through Closures in a returned Object. Again, difficult to describe textually; here is an example:

var YUIObject = function(v1, v2) {
var v1 = v1;
var v2 = v2;
return {
testFunction: function() {
alert(v1);
}
}
};
// to use
var someVariable = new YUIObject (v1, v2);
someVariable.testFunction();

So, this Object basically does the same thing as the PrototypeObject. The constructor call, instantiates the Function YUIObject, passing in two variables. Inside the scope of the Function those variables are redeclared to attach to the Function scope. Then the function returns an Object that ’someVariable’ will be set to. The ‘testFunction’ has access to v1 and v2 inside the Function scope because of Closures. For me this Architecture is easier to read and simpler to use, so I have built most of my Objects this way. The downside is that Closures leak memory like sieves in IE, if you are not careful.

To wrap up our discussion, I have created a page where you can compare the run times of the different instantiation. Unfortunately, JavaScript run-times aren’t very accurate and depend on the idle time of your computer. Having run it many times though in many browsers, I can summarize that on average the initialization of the YUI-type Objects is 35-45% faster than the Prototype Objects. Although, we’re talking about fractions of a millisecond, so you’re only going to notice this when you are creating thousands of Objects.

http://mattsnider.com/PrototypeVsYUITest.html

posted by Matt Snider at 8:20 pm  

6 Comments »

  1. I’m a big fan of Prototype’s collections and DOM utils, but the OO implementation is curious.

    The Class.create() method seems to eschew any sort of encapsulation - I’m not sure how that’s OK, no matter what language we’re working with.

    Also keep in mind the inheritance gotchas with Prototype:
    http://www.encytemedia.com/blog/articles/2006/05/23/prototype-inheritance-madness

    Comment by Geoff Moller — May 15, 2007 @ 12:04 pm

  2. […] This post at mattsnider.com talks extremely briefly about Javascript object creation. It goes on to compare Prototype’s class definition method versus the standard pattern present in the YUI Library. While I often favor an approach even more traditional than the YUI pattern, the Yahoo! pattern maintains encapsulation. The Prototype abstraction of class definition is a great example of “places where Javascript libraries shouldn’t go.” […]

    Pingback by When Javascript Libraries Attack at geoffreymoller.com — May 15, 2007 @ 2:27 pm

  3. Thanks for the comments Geoff. You make a good point.

    Comment by admin — May 21, 2007 @ 10:02 am

  4. […] Geoffery Moller, I came across this article on Matt Snider’s blog. I’m surprised that no one noticed what (to me) was the most […]

    Pingback by Foo Hack » YUI’s “Module Pattern” vs. Prototype’s Class Function — August 13, 2007 @ 10:54 am

  5. When you’re talking about real-world objects with large or many functions in them, Prototype’s approach to object creation is going to win in terms of memory usage, when you have multiple instances of the same object. Any methods attached to a class’s “prototype” are shared between all instances of the class. Because YUI doesn’t seem from your example to use the prototype object, every instance of the class will get its own copies of all the functions.

    Comment by Joel — October 15, 2007 @ 2:53 pm

  6. Joel,

    Very true. For said reason, I also wouldn’t use the YUI module pattern with a large and/or frequently reused object. I reserve the Module Pattern for Objects that are initialized once, such as business logic and widget management objects.

    However, I also wouldn’t use the Prototype method, because you expose too much by attaching everything to the ‘this’ variable. Lately, I have been using a combination of overriding the prototype, lazy function definition, and proxy functions created using the Module Pattern.

    Comment by admin — October 15, 2007 @ 4:05 pm

RSS feed for comments on this post. TrackBack URI

Leave a comment

Powered by WordPress