dean.edwards.name/weblog/2006/05/prototype-and-base/

Prototype and Base

Woah! Sam Stephenson has a blog!

In his first post he discusses inheritance in his Prototype library. I’m a big fan of Prototype (I also like JQuery) and I’m pleased to see that he is considering using my Base class in his library (thanks to Justin Palmer).

I’ve made a couple of tweaks to the class since I last blogged about it. The most important change is that I’ve renamed the inherit method to base. I caved in to pressure.

These are the other small changes:

I still think the Base class can be improved. For example, extending a prototype object after it has been subclassed will not effect a previously established inheritance chain. I think this is fixable though. I’d be interested to see if Sam and the other Prototype hackers can improve the class further. But I’d like to keep the class short and sweet if possible.

The development area is a little bit broken at the moment. I’ll update it properly soon and put out another shiny blog post to describe some of the classes I have built with Base.

Comments (60)

Leave a comment

I’ve been playing with Base a lot during the past couple days – having that Base(widget) wrapper will be really nice. I have a stripped down version working with a personal copy of jQuery, so that I can do the following:

$("div.foo li")[0]

or even:

$("div.foo li").detect(function(li){
  return li.name == 'foo';
});

which is a combination of jQuery, Base, and Prototype-enhanced Array notation (Since Prototype extends the Array object with its own methods and my modified version of jQuery is a sub-class of the Array object). I’m definitely going to play around with it some more and release what I have for everyone else to use, on the jQuery mailing list.

  • Comment by: John Resig
  • Posted:

Hey, Dean,

I tripped over a really insidious bug the other day (working on my own inheritance scheme, the #4060 which Sam gently disses in his blog post :/ ).

In this code from Base.js, you need to protect the method call from exceptions thrown internally (periods just for indentation):

value = function() {
	var previous = this.base;
	this.base = ancestor;
	var returnValue = method.apply(this, arguments);
	this.base = previous;
	return returnValue;
};

Something like the following is needed:

value = function() {
	var previous = this.base;
	this.base = ancestor;
	try { var returnValue = method.apply(this, arguments); }
	catch (ex) { throw ex; }
	finally { this.base = previous; }
	return returnValue;
};

Otherwise, the statement “this.base = previous” will be skipped if an exception is thrown inside the method call.

Cheers, Ben

P.S. How would you feel about working together on this whole thing? I’ve given a lot of thought to the same issues, and a new inheritance system will be a rather critical element of the 2.0 version of Prototype. We should do it right.

  • Comment by: Ben Newman
  • Posted:

@John – I’d like it if all Base constructors could be used to cast native objects. e.g. WidgetClass(element); I think this is doable (just not sure how yet).

I’d be interested to see the work you’ve done. It sounds similar to some of the things I am writing and it looks like Prototype is becoming more JQuery-like too.

@Ben – Thanks for that fix! I was hoping that the Prototype gang could improve Base and you already have! I’d be happy to help out integrrating Base with Prototype. I’m hoping that the process will improve both sets of code.

@Both – It seems that our work overlaps in certain areas. I’m not suggesting we join forces to build a mega-library (we’ll leave that to others) but let’s keep an eye on each others work. We should not be afraid to co-opt good techniques from one library into another.

One more thing, both JQuery and Prototype have fantastic iteration methods. Mozilla provides very similar methods natively. Why not use those methods on a Mozilla platform? e.g. use forEach instead of each. That way you get a speed boost for those 15% of people who use a Mozilla browser.

  • Comment by: -dean
  • Posted:

[…] norati.com/tag/Articles” rel=”tag” title=”View the technorati tag: Articles”> Dean Edwards came up with Base as a way to give nice inheritence management in JavaSc […]

By the way, the thing I like most about your system is that your syntax (calling extend() on an existing class) makes it seem like single inheritance is the most natural thing in the world. I specify the base class with a property (“extending”), which has always felt a little arbitrary. Might co-op the idea from ya:)

Ben

  • Comment by: Ben Newman
  • Posted:

I’m probably being dense, but I can’t figure out how to create a class that extends a DOM class. When I try the following in Firefox:

var divBase = document.createElement("div");
Base(divBase);
var MyDiv = divBase.extend({
 constructor: function(name) {
   this.name = name;
   this.appendChild(document.createTextNode(this.name));
 },

  yo: function(){
   alert("yo");
  }
});
x = new MyDiv();
x.yo();

I get this:

uncaught exception: [Exception... "Cannot convert WrappedNative to function" nsresult: "0x8057000d (NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN)" location: "JS frame :: >a href="http://www.example.com/test.html"<http://www.example.com/test.html :: >top_level< :: line 27" data: no]

Any thoughts on how to make this work? Thanks!

  • Comment by: Ben Marklein
  • Posted:

which is a combination of jQuery, Base, and Prototype-enhanced Array notation

Comment by John Resig

Digg,  Del.icio.usMa.gnolia:-P

  • Comment by: -dean
  • Posted:

@Ben Marklein – When you extend an object you are adding to its properties. When you extend a class you are creating a new class. In your example MyDiv is not a constructor function. It is an object.

@Ben Newman – single inheritance is the most natural thing in the World.;-)

  • Comment by: -dean
  • Posted:

Thanks. So is there a way to accomplish what I’m trying to do? Calling “new HTMLDivElement()” results in an error, “document.createElement(‘div’)” is the only way I know of that works. So, is it possible to create a “subclass” of a DOM class like HTMLDivElement? Thanks again!

  • Comment by: Ben Marklein
  • Posted:

@Ben M – No. It’s not possible.

  • Comment by: -dean
  • Posted:

It seems like everyone’s looking for a better Javascript class declaration/inheritance model at the same time. I just started developing my own solution a few days ago. I plan on making an initial release available for everyone to criticize soon (possibly this weekend). It will support/enforce abstract methods, final methods, static methods/values, static initializers, interfaces (interfaces can extend multiple interfaces and classes can implement multiple interfaces; errors thrown when class is declared if it does not fully implement all interfaces), etc. Here’s a preview of what it looks like to create classes with my library (Dean, I hope you don’t mind that stole the name ‘base’ as a reference to the base version of an overriding method):

// interfaces require that you provide dummy functions... 
// this is to force you to put some possibly useful info about how the
// implementations are expected to behave
$interface("Shape", {
  getPerimeter: function() {
    return Number();
  },

  getArea: function() {
    return Number();
  }
});

$interface("Named", {
  getName: function() {
    return String();
  }
});

$class("Something", {
  getName: function() {
    return $class.typeOf(this);
  }
});

$class("Rectangle", {
  // just an example that extending a class can satisfy requirements
  // of implementing an interface method
  $extends: Something,
  $implements: [Named, Shape],

  $constructor: function (width, height) {
    this._width = width;
    this._height = height;
  },

  // example of a final method... can't be overridden by an 
  // inheriting class
  getWidth: $final(function() {
    return this._width;
  }),

  getHeight: $final(function() {
    return this._height;
  }),

  getPerimeter: function() {
    return this.getWidth() * 2 + this.getHeight() * 2;
  },

  getArea: function() {
    return this.getWidth() * this.getHeight();
  }
});

$class("Square", {
  $extends: Rectangle,

  // this.$base is available in any member function that overrides
  // a base class's function
  $constructor: function (width) {
    this.$base(width, width);
  },

  // example of a static property (accessed as Square.createSquare)
  createSquare: $static(function(width) {
    return new Square(width);
  }),

  // static initializer example
  $static: function() {
    alert("Square has been declared");
  }
});
  • Comment by: Jeff Lau
  • Posted:

@Jeff – this looks kind of interesting. Can you ping me when it is released?

  • Comment by: -dean
  • Posted:

@Ben M: There actually is a way to do what you want. You have to use the DOM object as the prototype for your constructor function, and add all the extra properties to that object before calling the constructor. The problem is that DOM objects aren’t just their lists of properties — they have some internals that can’t be copied into your new object. I’ve gotten this to work in my scheme. See http://groupspace.org/devben/proto-svn/demo, and check out the examples on mimicking DOM objects. Unfortunately, this will never work in Safari, for completely brain-dead reasons. Safari requires that anything inserted into the DOM has to have been created by a native function, like document.createElement, so you’re stuck creating your DIV in the usual way, adding some properties to it, and document.appendChild’ing it. No chance for inheritance:(

@Jeff: Good luck with this. Your syntax is nice, but I’ll be interested to see how much code the implementation requires! There are some hidden thorns in this kind of project, and I’ll be happy to share them once you’ve released something:)

  • Comment by: Ben Newman
  • Posted:

It will be more interesting to be able to add more than interface at once ?

FlyingFish = Fish.extend(); FlyingFish.implement(Bird,OtherInterface[,…]);

Base.implement = function() { for( var i = 0; i < arguments.length; i++ ) { _interface = arguments[i]; if (_interface instanceof Function) _interface = _interface.prototype; this.prototype.extend(_interface); } };

Sorry for the previous unreadable code

Base.implement = function() { 
    for( var i = 0; i < arguments.length; i++ ) { 
        _interface = arguments[i]; 
        if (_interface instanceof Function) _interface = _interface.prototype; 
        this.prototype.extend(_interface); 
    } 
};

Mmm. I’m thinking of getting rid of that implement method now. I was a bit hasty introducing it (I was seduced by my own code sample). I don’t want to encourage multiple inheritance anyway.;-)

I now have constructor functions that can also be used to cast foreign objects. That means that the FlyingFish example is still possible but now the code looks like this:

var FlyingFish = Fish.extend()
Bird(FlyingFish.prototype);
  • Comment by: -dean
  • Posted:

I’m curious to see how you go about distinguishing constructor arguments from foreign objects when you call Bird() in your example above.

Would you be willing to make your latest code available in some form? This file is getting a little stale, judging by your recent comments: http://dean.edwards.name/base/Base.js

Ben

  • Comment by: Ben Newman
  • Posted:

@Ben – foreign objects is probably the wrong term. I mean that constructor functions can be used to cast objects too. I made the following change to Base.extend:

var klass = function() {
	if (!Base._prototyping) {
		if (this instanceof klass) {
			constructor.apply(this, arguments);
		} else {
			if (arguments.length) {
				return extend.call(arguments[0], _prototype);
			}
		}
	}
};

I’ll update the development area later. In the meantime, I’ve mailed you the latest version of Base.js. Although I’ve made some internal changes, externally all the interfaces behave the same.

  • Comment by: -dean
  • Posted:

@Dean – I finally released an initial version of my library in a blog entry. Please excuse my default WordPress theme :).

@Ben – Yeah, it’s a lot of code. My focus was useful functionality and aiding the development process of object-oriented code with helpful error detection/reporting. Once the functionality of my library settles down, I’ll start focusing on simplifying logic and reducing the file size. I could probably even have a smaller “production” version that skips error detection that is only useful during development. I guess it’s time for you to burst my bubble with those thorns you were speaking of :(.

  • Comment by: Jeff Lau
  • Posted:

@Jeff – I had a quick look and it looks well thought out. You can reduce file size by getting rid of those // ##### comment separators. I’ll play with your library a bit more later. See if there’s anything I can steal from it.;-)

  • Comment by: -dean
  • Posted:

@Dean – Duh, why didn’t I think of that before? I’m still in a transition from application development (in C++) where comments have no effect on the size or performance of the application.

  • Comment by: Jeff Lau
  • Posted:

all your Base are belong to us

  • Comment by: webman
  • Posted:

@Jeff:
kepp your comments for the development since they improve readability. For Production release you can use deans packer or kaes jsquash. These programs cut out comments and useless spaces and then compresss your source. Currently Kae and I are working on a C++ Version of his algorithm since the JavaScript implementation is not really fast.

For you as a C++ Developer it is a bit like compiling – you just don’t need to compile for testing. The Packer is a lot faster than jsquash but jsquash usually is a bit more efficient.

Sorry for posting again, but while reading jeffs code I found one advice: If you can leave our the curly braces, do so. I don’t know what the Packer does, but jsquash can not do that for you. Instead of:

  if (obj2) {
    for (var i in obj2) {
      if (!result.hasOwnProperty(i)) {
        result[i] = obj2[i];
      }
    }
  }

use

  if (obj2) 
    for (var i in obj2)
      if (!result.hasOwnProperty(i))
        result[i] = obj2[i];

The first step of jsquash gives you

if(obj2){for(var i in obj2){if(!result.hasOwnProperty(i)){result[i]=obj2[i];}}}

for the first code and for the second

if(obj2)for(var i in obj2)if(!result.hasOwnProperty(i))result[i]=obj2[i];

It is only six bytes less, but through your whole code it will summ up. The actual compression is of course done afterwards, but usually longer input produces longer output if the entropy is the same.

you can also save some bytes by using object literals for the prototypes:

$class.prototype = {
  getName: function() {...},
  getConstructor: function() {...},
  ...
}

Hope this helps.

Forbedring af nedarvning i Prototype Dem der har prøvet at arbejde med Prototype ved det formentlig allerede — nedarvning fungerer lidt klodset: var Subklasse = Class.create(); Subklasse.prototype = Object.extend(Object.extend({}, Grundklasse.prototype), { initialize…

@webman – I was wondering how long it would take someone to say that.:-)

  • Comment by: -dean
  • Posted:

Great, great library! Thanks!

Question though: if you use implement to cause object X to implement object Y, then X instanceof Y seems to return false. This is kind of important and I can’t figure out any way to determine if an object has been extended in this way. Can you point me to a solution for this issue? Thanks again.

  • Comment by: Joshua Frank
  • Posted:

@Joshua – Base does not support true multiple inheritance. That is beyond the bounds of JavaScript. The implement method will apply an interface to a class but there is no real connection between the objects after that. Indeed, if you extend the interface again, the target class does not inherit the new changes.

  • Comment by: -dean
  • Posted:

Hmm. Bummer. I have kludged around this by adding the following to Base.implement:

if(!this.prototype.implementedInterfaces)
    this.prototype.implementedInterfaces = [];
    this.prototype.implementedInterfaces.push(_interface);

And then I wrote up a custom instanceof function that would check to see if the interface was in the implementedInterfaces array:

function instanceOf(type)
  {
    //if we inherit directly
    if(this instanceof type)
      //we're indeed an instance of the type
      return true;
    //for each implemented interface
    var ret = $A(this.implementedInterfaces).detect
    (
     function(interface)
	{
	  if(interface == type.prototype || interface instanceof type)
	  return true;
	}
     );
   return (ret != null);
}

This works ok (relying for the moment on prototype, which others may not want to do), but I’m sure it could be much improved on. And the big drawback is replacing one of the Base methods, which is asking for breakage down the road.

So I guess the questions are: can you think of a more elegant solution, and is this something worth incorporating into the library?

Incidentally, I’m inclined to view multiple inheritance with a yuk, as you say, but multiple interface implementation is quite nice.

  • Comment by: Joshua Frank
  • Posted:

I began using base for a project a few days ago. The syntax simplicity is great–very easy to remember, so I never have to reference any documention. For a low-level paradigm like class inheritance, I believe this i essential. A concern of mine with base is the implied usage of its syntax for defining variables. Defining variables alongside functions does not work as it may in other languages.

Here is an example that demonstrates the problem:

var Example = Base.extend(
//instance
{
   //this doesn't work--must use constructor
   loved : "Dean",
   what_i_like_to_shout: this.loved.toUpperCase() + " I LOVE YOU!!!!"   
},
//static
{
   //depencies like this don't work 
   ChildClass : Base.extend(),
   GrandchildClass : ChildClass.extend(),
//init is required for resolve dependencies:
//the following is required so that definitions resolve...
// var obj = {Prop: val, Dependent : Prop }
//makes Dependent undefined, so we have to declare dependent
// members in the constructor
init: function()
{
   this.ChildClass = Base.extend();
   this.GrandchildClass = ChildClass.extend();
}
});

This is how I use your library in light of the dependence issue:

//an example class that makes no sense!
var Cummings = Person.extend(
//instance functions/data
{
   //###  Variable Declarations ###//
   //variables declared by Cummings
   vision          : null,

   //###  Function Definitions ###//
   constructor : function(win)
   {
      base();
      //### Variable Definitions ###//
      this.name = "E.E. Cummings"; //superclass property
      this.vision = true; //my property
   },
   otherfunc : function(){}

},
//static functions/data
{
   //### Child Class and Variable Declarations ###//
   ChildClass   : null,

//the following is required so that definitions resolve...
// var obj = {Prop: val, Dependent : Prop }
//makes Dependent undefined, so we have to declare
// dependent members in the constructor
init : function()
{
   //### Child Class and Variable Definitions ###//
   this.ChildClass = Base.extend();
}
});

Or maybe I just like C++ too much :>

  • Comment by: red daly
  • Posted:

Dean, thanks for this awesome library. I’m just beginning to appreciate the power and simplicity of it.

this.base() doesn’t seem to be available in constructor methods. Is this a bug or an omission by design?

For example,

var Node = Base.extend({
  id: null,
  constructor: function(id) {
    this.id = id;
  }
}); 
var Tree = Node.extend({
  constructor: function(id) {
    this.base(id);
  }
});

var tree = new Tree("MyTree");

In the above, tree ends up with a null id property as if the this.base(id) had never been called.

Any insight would be much appreciated.

@Justin – I just tried the exact same code as you posted above and it works fine.:-?

Also, you don’t need to specify the constructor in the Tree class. But it works the same either way.

  • Comment by: -dean
  • Posted:

@Dean – Sorry about the confusion. You are completely correct about the inheritance of constructors. In simplifying my example above from my original code, I did not copy the incorrectly spelled constuctor function in Node definition. My original code works fine with that correction.

Any ideas about if and when you’ll release the version you’ve hinted about that can extend HTMLElement objects? I’m using some kludgy mix-in logic to accomplish this right now. I’m very curious to see how you plan to tackle this.

Again, thanks for your help and keep up the good work.

Are you able to use inherited properties in subclass methods? In the simple example below, if I call class2.method(), then the correct value is shown, but if I call class2.method2() then the popup says “undefined”.

var Class1 = Base.extend({

    constructor: function()
    {
        this.inherit = true;
    },

    inherit: null,

    method: function()
    {
        alert(this.inherit);
    }
});

var Class2 = Class1.extend({

    method2: function()
    {
        alert(this.inherit);
    }
});

var class2 = new Class2();
class2.method(); // shows "true"
class2.method2(); // shows "undefined"

I’m relatively new to JavaScript, and am more of a Java programmer, so when I think inheritance, inherited properties should be able to be used in any subclass’ methods. Am I assuming incorrectly?

  • Comment by: Russ Zumwalt
  • Posted:

@Russ – I just tried the code above and got these results:

var class2 = new Class2();
class2.method(); // shows "true"
class2.method2(); // shows "true"

So there must be a typo somewhere in your original code.

  • Comment by: -dean
  • Posted:

I apologize for that. After some more debugging, the root cause of the problem was that class.method2() was getting invoked indirectly. I was using the Event.observe method from the Prototype library to attach additional behavior to an HTML element. Basically, “this” wasn’t what I wanted it to be, those Java habits die hard :-/. I found a workaround, but thanks for the help, hope it didn’t take too much of your time…

  • Comment by: Russ Zumwalt
  • Posted:

Hi Dean and all,

I’ve been using Base for a few days and I’m very happy with it!

I have a problem with inherited static members though:

        var class1 = Base.extend({
        }, {
            sfunc: function() {
                alert("static function for class1");
            }
        });

        var class2 = class1.extend({
        }, {
        });

        class1.sfunc();
        class2.sfunc();  // class2.sfunc is not a function

Looking at the code, I guess this is to be expected… so what would you think of adding this feature?

Cheers, Andrea

@Andrea – I am against adding this feature. It means that you end up with copies of data on descendant classes. Why do you want two ways to refer to a method anyway?

  • Comment by: -dean
  • Posted:

@Joshua – I think this is the most elegant solution yet, with that code you can easily determine extension of the required object. Don’t bother thinking about the implement method or going far away imagining the complex options.

  • Comment by: Jim
  • Posted:

It seems that istanceof operator don’t work in IE 4.0, I made ,using JSL(for array.prototype extension), a little fix,changing istanceof in typeof, since you use istanceof only against Function.

examples:

Base.implement = function(_interface) {
	if (typeof(_interface) === "function") _interface = _interface.prototype;//work in IE 4 and is the same.
	//if (_interface instanceof Function) _interface = _interface.prototype;
	this.prototype.extend(_interface);
};

there is 3 replace to do and after that your Base work on IE 4.0 (!!);)

@kentaromiura – typeof doesn’t always work. Annoying isn’t it? I would like to get rid of the instanceof operators in Base as Mac IE5 does not support it either (I am less concerned with IE4.0).

  • Comment by: -dean
  • Posted:

[…] An easy way to inherit a class, call the parent’s constructor, call a parent’s version of a method, and to set members as protected, private, or public. There are examples that go towards achieve this; but, native support is magnitudes of an improvement just for the sake of improved readability. (It would be really sweet to have reflection.) For what Mozilla is planning for Javascript 2.0, a more traditional class support will be added. […]

didn’t even know it ;P thanks for pointing out this, ain’t concerned too in IE4, it was just for the sake of it;) i’ll work on it. bye!

function isFunction(x){
alert(typeof(x)==="function" && (typeof(x.toSource)==="undefined" || x.toSource().charAt(0)!="/"))
}

tested in IE 4.0 , IE 6.0, NN 7.2(is the same as FF 1.0) FF 1.5.0.1 and Opera 8.51, if you can test on IE Mac i’m pretty sure that works;)

isFunction(new RegExp()) -> false
isFunction(function(){}) -> true

Hi dean.

Simply loving it. I tried to write my own implementation of a nice inheritance lib for prototype, but i ran into yours searching for solutions of bugfixes for my own lib.

This fits my needs exactly and i’m happy not to have to spend more hours on things i shouldn’t be worrying about:)Next time i’ll check your blog (among others) before trying to fix things myself;)

Keep up the good work.

  • Comment by: drm
  • Posted:

Hi Dean,

Great piece of code. You’re making everyone’s life much easier and thanks a lot for that.

I started playing with Base then and noticed something that I can’t logically explain. The “delete” javascript keyword doesn’t set properties to undefined on extended objects but resets the property value back to its original one set in the object literal passed to Base.extend.

The following example alerts “value 2” first, but instead of “undefined” it alerts “value 1” the second time.

Is this a bug, or am I missing something ?

var Foo = Base.extend({
    test: 'value 1'
});

var f = new Foo();
f.test = 'value 2';
alert(f.test);
delete f.test;
alert(f.test);

@Cyril – This is not a bug. This is standard JavaScript at work. Inheritance is provided by a chain of objects (prototypes). When you delete a property from a descendant class you will revert back to the value defined on the object’s ancestor. No way round that and nor should there be. You can always set the property to null instead.

  • Comment by: -dean
  • Posted:

Indeed, I had refered to the Mozilla doc which doesn’t mention anything regarding inheritance and just says delete sets properties to undefined.

Thanks for (very quickly) clarifying this. And thansk again for Base !

where do u take the test

  • Comment by: huh
  • Posted:

A simple Observer / Subscriber implementation using Base

:bye:

Hi,

I’ve found if your method body includes the word “base” _anywhere_ (ie. in a comment), it will be treated as an override.

  • Comment by: mr.a
  • Posted:

Or maybe not… sorry for the comment, i’m still checking, but it should be my bug…

  • Comment by: mr.a
  • Posted:

[…] Dean Edwards: Prototype and Base Classical Inheritance in JavaScript OOP in JS, Part 1 : Public/Private Variables and Methods Javascript Closures Es gibt aber auch ein paar Frameworks die die n?en Funktionen bereitstellen: ActiveWidgets Prototype JavaScript Framework: Class-style OO, Ajax, and more […]

test

  • Comment by: test
  • Posted:

So how would one get private variables used in the following fashion:

var f = function () { var private = ‘abc’; this.print = function () { alert(private); } }

Working under Base? Using the constructor/this.extend combo illustrated in the original post does not seem to generate any disco.

  • Comment by: Sam
  • Posted:

Is it intentional (or unavoidable..? now that I have thought about it a bit) that the keyword ‘this’ in the constructor points to the static class definition? the following resets the class definition of options (Test.Base.options), took me a while to figure out just what was happening with my class heirarchy..!

at the very least, a warning to the unwary: dont do the following..

var Test = {}
Test.Base = Base.extend({
constructor: function (options)
{
    this.options = options
}
},
{
    options: {name: "Test.Base"}
})

new Test.Base("blah blah")

following this, Test.base.options == “blah blah”

Great work, Base solves a lot of problems, and a great name… makes me think of “Base Class”… it works for me.

I have been doing a lot with prototype and i think this article would be helpful for other readers… http://positionabsolute.net/blog/2007/04/javascript-class.php

A “trick” that i have found to work quite well for your “Super” dillema is to statically instantiate the “super” class’s method in the sub’s function

Super.prototype.initialize.apply(this, arguments);

You can do that with any of the super’s functions to inherit its functionality, its not ‘sweet’ syntax but it gets the job done and it will inherit correctly in a sub-sub class.

kepp your comments for the cadence since I myself crown readability. For Production shapable you can use deans packer or kaes jsquash. These programs cut out comments and useless spaces and heretofore compresss your source. Currently Kae and I are dynamic on a C++ Version of his algorithm since the JavaScript implementation is not forsooth fast.

For you as a C++ Developer it is a bit like compiling – you just don’t commitment to round up for testing. The Packer is a lot faster precluding jsquash but jsquash usually is a bit and all equal to.

[…] gegenseitig keinesfalls aus. Es muss auch nicht extra eine umfangreiche Klassenbibliothek (z.B. Dean Edwards Base Class) verwendet werden, um klassenähnliche Konstrukte einfach definieren zu können. Jediglich 15 […]

[…] Base.js : http://dean.edwards.name/weblog/2006/05/prototype-and-base/ […]

Comments are closed.