JS Methods, static and instance

Posted in javascript by Kris Gray on December 21st, 2009

When you start having objects in your code, its only natural that methods would follow. With methods there are many different ways to define them, all have various side effects so it’ll be important to know why one is preferable to the other.

Instance method in object

  1. function FooObject() {
  2.    this.mBar = function(){};
  3.    this.mBlah = fnBlah;
  4. }
  5.  
  6. function fnBlah() {}

Here we have an object FooObject, and every time we instantiate it, it gets methods of mBar and mBlah on it.

The primary thing to consider here is that every time you instantiate an instance of FooObject, a new copy of the function assigned to mBar is created. So we have a memory penalty.

We also get two extra operations which assign functions to the two method properties of our FooObject for each new instance of FooObject.

Though because mBar's function is defined inside of the FooObject, it does have access to its scope via closure. Which is something.

Instance method on prototype

  1. function FooObject() {};
  2. FooObject.prototype = {
  3.    mBar: function() {},
  4.    mBlah: fnBlah
  5. }
  6.  
  7. FooObject.prototype.mBoo = fnBoo;
  8.  
  9. function fnBlah(){};
  10. function fnBoo(){};

Assigning to the Prototype of your new class has some major advantages. The prototype object is consistent for each instance of the FooObject, so you don’t have extra operations for each method you assign on each object instance.

You can specify a new blah method that will inject itself as first into the chain to be called, yet still maintain a copy of the old method.

  1. // New FooObject with a blah method which alerts a string.
  2. function FooObject(){};
  3. FooObject.prototype = {blah: function(s){alert(s)}};
  4.  
  5. // New instance of Foo Object
  6. var x = new FooObject();
  7.  
  8. // Redefine the Blah method, now it should prompt instead of alert.
  9. x.blah = function(s) { prompt(s,s); };
  10.  
  11. // Call the original blah method which alerts.
  12. FooObject.prototype.blah.call(x, 'asdf');
  13.  
  14. // Call the blah method on our instance, it will prompt not alert.
  15. x.blah('xyz');

A note about assigning to the prototype though, if your doing inheritance, you’ve just blown up your inheritance chain. Here’s some code to show you what I mean.

  1. function Animal(){};
  2. function Cat(){};
  3.  
  4. // Cat is an animal
  5. Cat.prototype = new Animal();
  6.  
  7. // Uhhh yea, now its no longer an animal
  8. Cat.prototype = { 'meow': function(){} }

Its because of this most (all?) of the JS Libraries out there would end up Iterating over the Animal class and assigning all its properties to the Cat prototype. Its a bit of a brute force technique, but its what must be done.

The only thing I dislike about this method is how clean looking it is. I’m not a fan of having your methods declared after your object all the way down the page, its just not very easy on the eyes. But with using a method like Mootools’s Class.Implement you can still use this basic technique with it still looking good.

Static Methods

With static methods, we want to call the method from the definition of the object, not an instance of it. Since functions are essentially objects themselves, we can add whatever we like to them.

  1. function Animal() {};
  2. function Cat(){}
  3. Animal.GetName = function(petObj){};
  4.  
  5. // This works
  6. Animal.GetName(new Cat());
  7.  
  8. // FAIL!
  9. new Animal().GetName(new Cat());

Since Static methods are declared on the declaration it doesn’t get inherited. Thus, there is no Cat.GetName().

No comments

Google Ajax Libraries APIs, Mootools is a little lazy

Posted in javascript by Kris Gray on July 28th, 2008

Have you heard of the Google AJAX Libraries API hosting service before?

From their website…

The AJAX Libraries API is a content distribution network and loading architecture for the most popular open source JavaScript libraries. By using the Google AJAX API Loader’s google.load() method, your application has high speed, globaly available access to a growing list of the most popular JavaScript open source libraries

Ignore that part about the google.load part, its really not necessary and just makes you include a JS file thats not really needed. The usage page provides URL’s for you to include on your page that load either the full version of the library or a YUI compressed version.

The important bits of the above quote really though are

  • Content Distribution Network for one of your JS files, usually one of the larger files.
  • As browsers have limits to the amount of files they can download from one domain, this allows the browser to download this file while it otherwise would have been waiting in the download queue.
  • Files are cached based on their URL, and if you would have happened to already have visited a site that uses this same library and version of that library then you’ll skip downloading it on this site. Thats right, partial page caching, even if you’ve never visited the site.

After news of this feature broke, we had a large email chain at our office about putting one of the most core files for your site out of your control. Back and forth we went, even some snide remarks, but essentially theres no way around the trust issue. You can have your own backup plans for if the file isn’t included, but now your adding complexity for a relatively small gain, and at that point you might as well just include a local copy of the library and skip the Googl eAPI completely.

The Google API supports 5 (4 really) libraries that you can remote load this way.

Though unfortunately MooTools is a little behind the times.  1.2 was announced on June 12th, thats a month and a half ago from the creation of this post and its still not in the Google API. I checked the other libraries and they are all up to date, but haven’t been updated since this service went live. So we don’t yet know if this is a service that will be going stale as time progresses.

2 comments

JS Beautifier, yay!

Posted in javascript by Kris Gray on November 20th, 2007

No longer are we constrained to the formatting of everyone else’s horribly formatted code!

Discover the coolness of JS Beautifier

This takes poorly formatted JS and adds indentations and line breaks.

Now if someone could make a nice easy one for HTML/XML I would be set.

No comments

Assert Class for JSUnit

Posted in javascript by Kris Gray on November 2nd, 2007

We use JSUnit at work, and I hate its assert methods.

assertEquals(comment, val1, val2);

YUK, the comment first? Coming from a C# background, this is about as ugly as you could imagine. So for eProject I wrote this simple class to get back to the norm.

var Assert = {
“AreEqual”    : function(val1, val2, comment) { assertEquals(comment, val1, val2) },
“AreNotEqual” : function(val1, val2, comment) { assertNotEquals(comment, val1, val2) },
“Fail”        : function(comment) { fail(comment); },
“IsTrue”      : function(val1, comment) { assertTrue(comment, val1); },
“IsFalse”     : function(val1, comment) { assertFalse(comment, val1); },
“IsNull”      : function(val1, comment) { assertNull(comment, val1); },
“IsNotNull”   : function(val1, comment) { assertNotNull(comment, val1); },
“IsNaN”       : function(val1, comment) { assertNaN(comment, val1); },
“IsNotNaN”    : function(val1, comment) { assertNotNaN(comment, val1); },
“IsUndefined” : function(val1, comment) { assertUndefined(comment, val1); },
“IsNotUndefined”: function(val1, comment) { assertNotUndefined(comment, val1); }
};

If you hate it too, then by all means, feel the love of the Assert class.

No comments

Note to self: Use qooxdoo to do something coo

Posted in javascript by Kris Gray on June 1st, 2007

http://qooxdoo.org/

They got some pretty sweet looking components as shown below.

Icon Bar

Bar View

List View (sweeeeet)

List View

There are several others you can see on their screen shots section .

No comments

Next Page »