dean.edwards.name/weblog/2006/03/base/

A Base Class for JavaScript Inheritance

NB. I’ve amended the code samples below to reflect recent changes in this class.

I’m an OO programmer at heart and JavaScript supports prototype based inheritance. Unfortunatley this leads to verbose class definitions:

function Animal(name) {};
Animal.prototype.eat = function() {};
Animal.prototype.say = function(message) {};

I want a nice base class for JavaScript OO:

The Base Class

I’ve created a JavaScript class (Base.js) that I hope eases the pain of JavaScript OO. It’s a simple class and extends the Object object by adding two instance methods and one class method.

The Base class defines two instance methods:

extend

Call this method to extend an object with another interface:

var object = new Base;
object.extend({
	value: "some data",
	method: function() {
		alert("Hello World!");
	}
});
object.method();
// ==> Hello World!
base

If a method has been overridden then the base method provides access to the overridden method:

var object = new Base;
object.method = function() {
	alert("Hello World!");
};
object.extend({
	method: function() {
		// call the "super" method
		this.base();
		// add some code
		alert("Hello again!");
	}
});
object.method();
// ==> Hello World!
// ==> Hello again!

You can also call the base method from within a constructor function.

Creating Classes

Classes are created by calling the extend method on the Base class:

var Animal = Base.extend({
	constructor: function(name) {
		this.name = name;
	},
	
	name: "",
	
	eat: function() {
		this.say("Yum!");
	},
	
	say: function(message) {
		alert(this.name + ": " + message);
	}
});

All classes created in this manner will inherit the extend method so we can easily subclass the Animal class:

var Cat = Animal.extend({
	eat: function(food) {
		if (food instanceof Mouse) this.base();
		else this.say("Yuk! I only eat mice.");
	}
});
	
var Mouse = Animal.extend();

Class Properties and Methods

A second parameter passed to the extend method of a class defines the class interface:

var Circle = Shape.extend({ // instance interface
	constructor: function(x, y, radius) {
		this.base(x, y);
		this.radius = radius;
	},
	
	radius: 0,
	
	getCircumference: function() {
		return 2 * Circle.PI * this.radius;
	}
}, { // class interface
	PI: 3.14
});

Note the use of the base method in the constructor. This ensures that the Shape constructor is also called. Some other things to note:

Classes With Private Data

Some developers prefer to create classes where methods access private data:

function Circle(radius) {
	this.getCircumference = function() {
		return 2 * Math.PI * radius;
	};
};

You can achieve the same result using the Base class:

var Circle = Shape.extend({
	constructor: function(radius) {
		this.extend({
			getCircumference: function() {
				return 2 * Math.PI * radius;
			}
		});
	}
});

The code is slightly more verbose in this case but you get access to the base method which I find incredibly useful.

Single Instances

I changed my mind a lot about this but finally decided to allow the creation of single instance classes by defining a null constructor:

var Math = Base.extend({
	constructor: null,
	PI: 3.14,
	sqr: function(number) {
		return number * number;
	}
});

Conclusion

This supersedes my old OO framework which was not as cross-browser as I would have liked (and had other shortcomings).

I have a development area where I’m developing bits and pieces based on this engine. Most of this is work in progress but illustrates the flexibility of this technique.

You can grab the Base class here: Base.js.

Update. I’ve posted a follow-up to this post with some improvements suggested in the comments below.

Comments (225)

Leave a comment

In the Circle examples you have declared a method “area” which is “perimeter” instead;-) Area is Math.PI *this.radius ^ 2

Anyway it’s really a simple and effective system to simplify class declaration and inheritance.

  • Comment by: Franco Ponticelli
  • Posted:

The JS inheritance class that I use is from Doug Crockford. It’s a nice simple class inheritance base class that just modifies the main Function class. It supports calling parent methods and doing multiple inheritence (which thus far I have never found a need for)

The only change I had to make from his code to make it fully cross-browser (opera had some issues) was to change his declaration of ‘uber’ in the ‘inherits’ method to NOT specify “function uber(name)” but instead use “function (name)” (anonymous function).

  • Comment by: Edward Rudd
  • Posted:

@Franco – Oops! Fixed now. Thanks. Maths was never my strong point (actually it was but I’ve now forgotten everything:-))

  • Comment by: -dean
  • Posted:

What benefits do you think this has over the Object.extend() and Class.create() features of Prototype?

not work in firefox

“prototype.call is not a function”

  • Comment by: modi
  • Posted:

@modi – What doesn’t work?

  • Comment by: -dean
  • Posted:

I got message “prototype.call is not a function” in Javascript Console when i try to Creating Class

  • Comment by: modi
  • Posted:

@modi – you are going to have to show me some code. I’ve created dozens of classes in Firefox and have not seen the error you mention.

  • Comment by: -dean
  • Posted:

I was also about to ask the same thing as Jonathan…

  • Comment by: Mislav
  • Posted:

@Mislav/Jonathon,

There is nothing wrong with Prototype’s method. I prefer mine for the following reasons:

  1. the inherit method
  2. readability

It’s like comparing x=x+1 with x++. A slight improvement but an improvement nonetheless.

Read this for a better explanation: http://www.sitepoint.com/blogs/2006/01/17/javascript-inheritance/.

  • Comment by: -dean
  • Posted:

As for readability, I see hardly a difference. As for the inherit method, this is really a blank spot in prototype.js

Unless you apply the patch from http://dev.rubyonrails.org/ticket/4060

  • Comment by: Martin Bialasinski
  • Posted:

@Martin – This is not designed to compete with Prototype. If people are comfortable with that library then they should continue using it. I wrote this for my own needs and I thought I’d share it.

  • Comment by: -dean
  • Posted:

Dean, I think when you’re writing “overload”, you mean “override”.

Two method declarations of the same name but different parameter lists are said to be “overloaded”. This isn’t possible in JS (unless you count using the arguments object and inspecting the passed argument types).

A method reimplemented which was defined in a superclass is said to be “overridden”.

Right?

  • Comment by: Jeremy Dunck
  • Posted:

Ah, that really makes a difference. I particulary like Ben’s patch; thanks for the link, Martin.

Dean: about singletons… The example provided isn’t exactly a singleton pattern, just a class that cannot be instantiated with some class constants and methods. I would call that a static class (or something like that), not a singleton.

And why did you choose to call the method inherit? Wouldn’t sup or super or parent be a better name?

Apart from that I like the work you’ve done very much, especially the clear examples.

  • Comment by: Mislav
  • Posted:

Dean, I never thought you want to compete with prototype.js, and I am certainly not a “XY already has this, no need for this” fan-boy. Sorry if this is what it looked like.

More choices are good, and one can always learn from other code, especially if it is yours, and adapt ideas. So thank you for sharing some of your work once again.

  • Comment by: Martin Bialasinski
  • Posted:

[…] art man, and wasn’t happy with any Base classes out there in various libraries so he wrote his own Base.js. His goals: I want to easily create classes without the MyClass.prototype […]

var Animal = Base.extend({
	constructor: function(name) {
		this.name = name;
	},

	say: function(message) {
		alert(this.name + ": " + message);
	}
});

Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.7.12) Gecko/20050919 Firefox/1.0.7

  • Comment by: modi
  • Posted:

Nice work.

In the private data example, did you mean to use just ‘radius’ in the formula instead of ‘this.radius’, as in…

var Circle = Shape.extend({
	constructor: function(radius) {
		this.extend({
			getCircumference: function() {
				return Math.PI * radius * radius;
			}
		});
	}
});
  • Comment by: Steve Yen
  • Posted:

@modi – Fixed now. Thanks for letting me know. I had to rename a variable from prototype to _prototype in a couple of functions. Presumably this is a bug that has been fixed in later versions of Firefox.

  • Comment by: -dean
  • Posted:

@Jeremy/Mislav – I’ve changed the text of the post. I now use the expressions “override” and “single instance”. Thanks for correcting my poor use of computing terminology.;-)

@Steve – Fixed now. Thank you.

  • Comment by: -dean
  • Posted:

Just a detail… I think inherit should be called something different. (It’s a semantic thing only, nothing wrong with the code in itself)

When you call baseclass.extend it is correctly a verb and your action is that expressed by the verb: extending your base class. But if I understood this correctly, when you call this.inherit you’re not really inheriting something, but actually calling the inherited method. The difference is subtle, I know, but it somehow doesn’t seem completely right.

I might suggest inherited instead, if you want to keep the inherit root, or something along the lines of what Mislav suggested above.

  • Comment by: Gonzalo
  • Posted:

What do others think of the name inherit? Any other ideas? ancestor? I don’t like the other suggestions much (inherited, parent, sup) and super is already a reserved word.

  • Comment by: -dean
  • Posted:

I have a couple of questions:

Whats the use of “…If you define a class method (not an instance method!) called init then will it …”, I thought thats what the constructor method was for.

Also this may be a newb question but when you stated that the ‘… second parameter passed to the extend method of a class defines the class interface’ in your example does is the PI property set the to Shape class?

– Thank you for all your contributions8)

  • Comment by: John
  • Posted:

BTW – I like ‘ancestor’ it gives me a better since of what its doing

  • Comment by: John
  • Posted:

Douglas Crockford proposed a long time ago the word uber. I’m not really sure I like it, but there it is anyway.

I do like ancestor. parent is ok too.

  • Comment by: Gonzalo
  • Posted:

@John – You can pass two parameters to class.extend. These parameters should be object literals. The first parameter defines the instance interface of the class. The second defines the class interface itself. You can perform class initialisation (rare but sometimes needed) by defining an init method on the class interface. This method will be called immediately the class is created. This is very different to the constructor function.

Below is a more detailed example. Class initialisation is required here because we need to close all open files when the document is unloaded. So we define an init method which adds an event handler:

var File = Base.extend({ // instance interface
	constructor: function(name, mode) {
		this.name = name;
		this.$guid = System.register(this);
		if (mode) this.open(mode);
	},

	$guid: 0,
	mode: 0,
	name: "",

	close: function() {
		delete File.opened[this.$guid];
		this.mode = 0;
	},

	open: function(mode) {
		this.mode = mode || File.READ;
		File.opened[this.$guid] = this;
	},

	read: function() {
	},

	write: function() {
	}
}, { // class interface
	CLOSED: 0,
	READ: 1,
	WRITE: 2,

	opened: {},

	closeAll: function() {
		var files = this.opened;
		for (var i in files) files[i].close();
	},

	init: function() {
		// class initialisation
		Event.add(window, "unload", this.closeAll, this);
	}
});

Does that makes sense? If you are not sure then ignore class initialisation.;-)Like I said, it is rarely need.

  • Comment by: -dean
  • Posted:

As for the name: inherited() looks like a test that returns a bool. Aside: I like that ruby allows questionmarks in names, like “SomeObject.inherited?”

“parent()” is nice, but might be too often used already in objects (to express the relationship between two objects like in the DOM).

Nice example in #26. Shows of the lib quite well. The class / instance interface distinction is very neat.

  • Comment by: Martin Bialasinski
  • Posted:

So the init is similer to the

var foo = Class.create(); Object.extend(foo,{

initialize: function(){ … } });

of Prototype?

  • Comment by: John
  • Posted:

foo = Base.extend({
constructor: function(){
this.bar = 3;
},
bar = 3 },

{
init: function(){
this.bar = 3;
},
bar = 3
});

In this example I have set bar in alot of places. In both the instance and class interface. Also in the construcor and init methods. They all do the same thing right?

If I only did it in the constructor method would alert(foo.prototype.bar); // still show 3

So I guess I dont see the need for an instance interface and a class interface, don’t they both do the exact same thing?

  • Comment by: John
  • Posted:

BTW thank you for taking your time to help and show examples8)

  • Comment by: John
  • Posted:

@John – You’ve missed the point slightly. Have another look at the example I posted.

  • Comment by: -dean
  • Posted:

More suggestions instead of “inherited”:

And all those suggesions prepended w/ “call”, so “callBase”.

  • Comment by: Jeremy Dunck
  • Posted:

Err, any chance of this being made MIT, BSD, AFL, or similar? LGPL? Really?

  • Comment by: Jeremy Dunck
  • Posted:

Hey, since this is a “refactored” version of common are we going to see an IDE? That was a fun project I thought (more so since I’ve started playing with smalltalk)

Anyway, Base is nice. I do agree with the folks that think the “inherit” method seems oddly named. I say forget all that tired language of “super”, “parent” or “inherit” and go with something new. I like “basis” as it goes well with the name Base. Mmm… “basis”

  • Comment by: mitchell
  • Posted:

So I just answered my own question about the IDE. I looked through your development area, and was stoked to see all that. Nice work! How long have you been at this? This has way more written on top of it then common ever did.

  • Comment by: mitchell
  • Posted:

@Jeremy – I’ll look at changing the license for this.

@Mitchell – Yes, common was fun and I managed to write at least one complex application using it. Base is more cross-browser. The IDE is unfinished. The IDE is useful for browsing object hierarchies but less useful for actually writing code. Until someone writes a decent text editor that is…

And you are right. The IDE is based on Smalltalk.;-)

  • Comment by: -dean
  • Posted:

Very nice. Not sure if I will use it since I’ve already written so much of my code using prototype but this is the cleanist implementation of class based OO I’ve yet seen.

I was a bit unclear about the point of the _static argument (i.e. second argument in Base.extend( , ) ). It seems to add methods just to the class but not to any instance variables but it also doesn’t seem to be inherited. Is this the intended behavior or am I just missing something in the code? I guess I’m just a bit confused as to what sort of OO model you have in mind with the static stuff.

One thought for future improvement. It seems possible that if you use object.extend inside an event handler or more likely the return from an XHR the global flag Base._prototyping could cause some problems. It seems possible to instead avoid the problem of calling the initializer when you new this by instead copying this to a temp variable renaming the constructoring calling new and then returning the constructor. However, maybe I am missing something.

  • Comment by: logicnazi
  • Posted:

@logicnazi – It is my intention that static methods and properties are not inherited. I’ve provided this mechanism mainly for the provision of class constants. Look at JavaScript’s Number class as an example of what I mean:

http://phrogz.net/ObjJob/object.asp?id=172

As to your other point. The Base._prototyping flag is only set when creating a class. It is not set when using object.extend.

  • Comment by: -dean
  • Posted:

Hmm… feels a lot like the Dojo toolkit’s ‘dojo.lang.extend’, except they’re missing a lot of the extended functionality you’re providing.

Might be worth a look, though, as you seem to be on the same track: http://manual.dojotoolkit.org/lang.html

  • Comment by: James Bennett
  • Posted:

Ohh right I see about the _prototyping flag. I retract my point. It would be kinda wastefull to add all that code for the crazy situation where people are defining new classes in event handlers.

Okay, now I understand what you meant by static. I was just a bit confused by the terminology.

Thanks alot for your response not to mention the library.

  • Comment by: logicnazi
  • Posted:

If I try to pass a function in a class, I lose the properties of that class. Any idea why?

var obj = new Base;
obj.extend({
	val    : 5,
	method : function(){ alert(this.val); }
});

var myMethod = obj.method;

obj.method(); // 5
myMethod();   // undefined
  • Comment by: Mark Kahn
  • Posted:

Mark – this is what should happen. When you call myMethod, the this value is pointing to the global (window) object. Because there is no window.val defined the function returns undefined.

  • Comment by: -dean
  • Posted:

@Mark:

Javascript “methods” are just functions hanging off an object– the “this” keyword isn’t bound to the object if you don’t scope it with the “.” operator.

Check out Boodman’s “hitch” function (which he called “close” in that post) — it makes the function do what you want

function hitch(obj, methodName) {
  return function() { 
    obj[methodName].apply(obj, arguments);
}

(from http://youngpup.net//2005/0525024806/comments#c1444 )

You’d change this line:

var myMethod = obj.method;

to this:

var myMethod = hitch(obj,’method’);

  • Comment by: Jeremy Dunck
  • Posted:

Hello.

Great tool Dean, I like it and I will start using it. Thanks.

Just two comments:

Thanks for your attention.

  • Comment by: knocte
  • Posted:

I have already converted IE7, packer and my syntax highlighter to Base. I haven’t released any of this code yet. Some of the classes are here:

http://dean.edwards.name/base/text/src/

  • Comment by: -dean
  • Posted:

Dean, I saw that you mentioned that you didn’t want to mess with the Object.prototype. Have you considered muffing with the Function.prototype instead? Like…something like this:

Function.prototype.method = 
	function (name, func) { 
		this.prototype[name] = func; 
		return this; 
	};

This typically shows up in Crockford’s toolkit and I’ve found it to be pretty nice.

[…] ebdesign imagereplacement) gotAPI.com :: API lookup service (tags: reference html css) A Base Class for JavaScript Inheritance (tags: javascript oop) […]

@Dustin – Yeah, this was the way I wrote it originally. But adding an override capability meant that I had to add the inherit mechanism too. It felt too much like I was extending the language rather than just adding a new class.

  • Comment by: -dean
  • Posted:

Dean, how would you use your library for implementing a class that contains both static and non-static members and properties in a class?

  • Comment by: Ympostor
  • Posted:

@Ympostor – An example of a class with both a class and instance interface is shown in Comment #26.

  • Comment by: -dean
  • Posted:

neat! the inherit() method is really useful but has been missing badly in other libs i have come across. don’t really like the name though. i vote for base() or super().

  • Comment by: oak
  • Posted:

Nobody likes inherit except me :-(.

super is already a reserved word. These are the alternatives that I like:

I’m still undecided…

  • Comment by: -dean
  • Posted:

What about polymorphism?

I implemented a fully supported but complicated Object Oriented JavaScript library: http://j2s.sourceforge.net/j2sclazz/ And the article: http://j2s.sourceforge.net/articles/oop-in-js-by-j2s.html

It seems it also fits all of your requirements of OO.

What about polymorphism?

Polymorphism is provided by inheritance. Quoting from your own document:

Methods can be overridden and polymorphism is supported

  • Comment by: -dean
  • Posted:

The polymorphism that I mean is methods with same name but different arguments, for example, aObj.action1(), aObj.action1(bObj). It seems that such polymorphism should be provided in a simple way.

And for the previous comment, I prefer to the keyword “$uper”.

$uper??? don’t get me wrong, but that’s an awful proposition

  • Comment by: Ympostor
  • Posted:

[…] es info How to boot Knoppix 4.0 from a USB Flash Drive DutchPIPE software A Base Class for JavaScript Inheritance Faster DOM Queries This entry was posted […]

Think about a more complex case:

var trace = function (str) {
    document.write(str + '<br />');
}

var C1 = Base.extend({
    constructor: function () {
        trace('C1.constructor call.');
    },
    m: function () {
        trace('C1.m call.');
    }
});

var C2 = C1.extend({});

var C3 = C2.extend({
    constructor: function (name) {
        this.inherit();
        trace('C3.constructor call.');
    },
    m: function () {
        this.inherit();
        trace('C3.m call.');
    }
});

var o = new C3; 
o.m();

The output is:

C3.constructor call.
C1.m call.
C3.m call.

But I think the output should be:

C1.constructor call.
C3.constructor call.
C1.m call.
C3.m call.

Here is the test page of the code above.

  • Comment by: kenxu
  • Posted:

@kenxu: This is not a bug. C2 is an empty constructor. When you call this.inherit from C3 you are calling C2 which does nothing. The output is as expected.

  • Comment by: -dean
  • Posted:

@kenxu: On second thoughts, I prefer your output. I will amend the Base class so that it no longer creates an empty constructor if none is supplied.

  • Comment by: -dean
  • Posted:

another name proposal for the inherit method

callParent();

Bye, Markus

  • Comment by: Markus
  • Posted:

Hello Dean, thanks for your class, it’s been a nice help already. I’ve just stumbled upon an oddity:

var Test = Base.extend({
	test: [],
	name: '',

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

	add: function(item) {
		this.test[this.test.length] = item;
	},

	print: function() {
		alert(this.name + " contains " + this.test);
	}
});

var t1 = new Test('test 1');
var t2 = new Test('test 2');

t1.add('one');
t1.add('two');

t2.add('three');
t2.print();

This alerts “test2 contains one, two, three”. So the “test” property is static over all instances of the class, even though I’m adressing it with “this”. If I initialize test in the constructor (with this.test = []), it does behave like an instance variable. Wouldn’t it be better if this were default behaviour? You could have static variables accessible through Test.test in stead of this.test (as in Java)

Just a thought:)

  • Comment by: Alex
  • Posted:

@Alex – there is already a mechanism for providing static variables. The example you supply does not look like an oddity to me. Object properties should be initialised in the constructor function.

  • Comment by: -dean
  • Posted:

Good stuff.

How about supr instead of inherit, like jsolait?

Coupla questions. Does Base support multiple inheritance? And is the constructor definition needed? In the Mouse case for example can’t the sleekit wee beastie simply inherit the Animal constructor?

The Package class looks interesting as well. Have you written about it anywhere? If not, care to spare a few words?

  • Comment by: chocolateboy
  • Posted:

@chocolateboy – I got rid of the need of the need to specify a constructor. From now on constructors are inherited as per comment #58

Yes, the Package class is interesting. I’m trying to avoid the verbosity of other JavaScript libraries. The Package class allows importing/exporting of namespaces to keep the JavaScript namespace clean. I’ll blog about it later when I’m totally happy with it.

BTW, I’m renaming “inherit” to “base”. I got persuaded by the crowd.;-)

  • Comment by: -dean
  • Posted:

@chocolateboy – Multiple inheritance? Yes.

I don’t trust multiple inheritance but the Base class supports it through the extend method:

FlyingFish = Fish.extend();
FlyingFish.prototype.extend(Bird.prototype);

I’m thinking of writing another function to make this easier. implement?

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

That seems good.:-)

  • Comment by: -dean
  • Posted:

Nice:-)

I’ve been evaluating this and jsolait (and had a look at j2Script) as the basis for a largeish library. I’m gonna go with Base. Please blog about Package when you get a chance. I want to play with that as well:-)

  • Comment by: chocolateboy
  • Posted:

I’m going to blog a bit more about Base in the near future. I’m just working out which classes should go in the core library.

The key features will be fast DOM queries, cross-browser event handling, a packaging system for clean namespaces (and readable code), a good collection class with powerful iteration methods and a binding mechanism for behavioral extensions. I’m going to try to squeeze that into a 15-20Kb file.

I’m also working on an object browser (like the Smalltalk IDE) and a mechanism for building documentation on the fly.

  • Comment by: -dean
  • Posted:

[…] (thanks to Justin Plamer). 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. […]

[…] ojectionist doesn’t count.) His first post is monumental: he all but guarantees that Dean Edwards’s Base will be integrated into Prototype, allowing for true inheritance. (I&#821 […]

You’ve renamed it to base? Blah:( It might as well be called über then, because that makes as much sense calling the overriden method as base

No offense, but I think these things should have semantics other than just functionality.

parent and super being reserved, maybe it can be called sup (if it’s not too late)? $uper, of course, is out of the question.

  • Comment by: Mislav
  • Posted:

@Mislav – what’s wrong with base? It seems whatever I call it there will always be someone that doesn’t like the name.:-(

  • Comment by: -dean
  • Posted:

Well, many people wouldn’t like sup either, but (as an abbreviation of super) it’s more correct. Unlike others, I have my arguments; base – as a word – is absolute and more like top. If someone asked me what do I think base method might be in an inheritance scheme, the first thing that comes to mind is that it might return the base class (top-level) of the inheritance structure. When one would give me a hint that it’s about methods, at first I would be puzzled, then I would think it might call the same method as implemented in the base class.

Because of the absolute nature of the word, I would never think it refers to something ‘one level above’. Ancestor is ambiguous, while parent is perfect – it is the first ancestor. Super (above; over; upon) is less ambiguous than ancestor because it usually implies ‘one level above’, eg. in ‘superclass’.

But you can’t change it forever, so if sup is ugly to some maybe it’s best to leave it like this. Note that when this ‘extension’ gets widely adopted (I’m sure it’ll be before it enters Prototype), changing the name would not be an option anymore.

Wow… It almost feels like we are making a language:)

One more suggestion… what about upcased names: Parent or Super? Just a thought…

  • Comment by: Mislav
  • Posted:

One more thing – I’ve just went through the examples again; this.inherit() was certainly the worst choice, glad you’ve changed it:)but the code examples need to reflect this change otherwise newcomers will be greatly confused without reading the lengthy discussion. This is just a reminder.

I’ve taken a look once more at Rails ticked #4060 for Prototype.js. Ben uses sup, but (in spite Ben’s explanation) one Frank tried to write this.sup.foo() and this.sup().foo(). This is an example how there are always people who would find something unlogical:)

Best of luck!

  • Comment by: Mislav
  • Posted:

@Mislav – I think that super is the only name that would have had universal acceptance. I chose base because, as someone pointed out, it is the same name as the framework. Not the best reason but no one likes the other names anyway.

The real problem is that what we are talking about is not really a method. Sure, it is invoked like a method but in real terms it is more like a keyword. This is the reason that I liked inherit in the first place – “inherit the behaviour of the super class”.

I’m not going to change it any more!:-)

  • Comment by: -dean
  • Posted:

I never had any strong feelings about ‘sup’. For being only three letters long, though, it evokes its intended meaning pretty well. But it is a little easy to mistake for an abbreviation of “superclass” (like ‘super’ in java). I think ‘base’ gets the point across just as well if not better.

Once I see which way the wind is blowing, I’ll be able to change the vocabulary by retyping the method name in just one place.

I’ve spent some quality time this afternoon slimming down my patch. It’s now less than twice the size of Base.js, and Dean’s awesome JS packer condenses them to within 1.5k of one another (he’s still winning though). The prototype library is ~60k (25k compressed).

I’ve also added a couple of lines of code that support Dean’s .extend() syntax. This was criminally easy;)

constructor['extend'] = function(declarations) {
  declarations['extending'] = constructor;
  return Class.create(declarations);
};

Underneath the syntactic sugar, Dean and I appear to be doing very similar things.

All the best, Ben

  • Comment by: Ben Newman
  • Posted:

Underneath the syntactic sugar, Dean and I appear to be doing very similar things.

And I’m silently lurking, waiting for you two to finish to overview both solutions, take out what’s best from the two and release it as my own mashup:P

Just kidding:)

Shame you don’t work together:?

  • Comment by: Mislav
  • Posted:

Hi dean, why is this possible? I built a lot around your base class, finding it needs fixing:(

var BaseView = Base.extend({

	vars: []

});

var ThisView = BaseView.extend({

	constructor: function () { this.vars.push('test'); }

});

var ThatView = BaseView.extend({

	constructor: function () { alert (this.vars[0]); }

});

var x = new ThisView;
var y = new ThatView;
  • Comment by: morriz
  • Posted:

@morriz – you haven’t really asked a question but I guess you are wondering why the alert shows “test”. It is because you need to initialize object properties in the constructor function. i.e.

var BaseView = Base.extend({
	constructor: function () { this.vars = []; },
	vars : null
});
  • Comment by: -dean
  • Posted:

Hi Dean, what do you mean? I think I dont get u right:(

Maybe its time for that question then:

Why does the class property ‘vars’ get changed when I instantiate an object and change its property? You clearly can see that it does. When I instantiate another class derived from the same base class, it gets the other childs instance’s value.

Actually I dont really need to now why this strange behaviour occurs. Can you tell me where I should declare class properties? Surely not in its constructor, that would kill a big part of the inheritance functionality :/

Maybe your init thingy could be used for that?

I will also try prototype to see if they have the same problem:)

  • Comment by: morriz
  • Posted:

Hi Dean,

prototype is not the answer…to say the least…but I found out more:

From trial and error it seems that simple properties like strings etc can be declared in the class and will be inherited as is,

BUT…complex structures like empty arrays and empty objects are instantiated and reused…I guess that is implicit to javascripts prototype model, but couldnt it be resolved somehow by managing these instances somewhere under water? That would be messy I guess, so I’ll have to do with prorotype’s limitations after all (thanks to guys like you to a limited degree that is:)But plz do let your mind go crazy on it, cuz it might lead to something ;]

cheerz,

Maurice

PS: I am too busy atm with work n all, otherwise I would love to dive in an not only be asking all the time:P

  • Comment by: morriz
  • Posted:

[…] this interface. The Special this.$base Property This feature was inspired by Dean Edwards’ Base class. When a class overrides a method of a class that it extends, a specia […]

Sorry to join so late, but what does “I want to easily create classes without the MyClass.prototype cruft ” mean?!

I have always rather liked the prototype syntax…

  • Comment by: Mark
  • Posted:

[…] cripting books. Here’s a rundown on what’s been happening. Dean Edwards’ Base class is on its way to being incorporated into Prototype. His Base class offers a clean way of […]

[…] áció) – Dojo (home) – Rico (home) – Scriptaculous (home) – Base OOP JavaScript(home, dokumentáció) Ezen kódkönyvtárak nagyrészt egymásra épülnek, melyek közül kiemelkedően […]

[…] 12;———– Just like Dean Edwards, I want an OO library that solves a number of problems. For convenience, here is Dean Edwards’ list. I want to easily create cl […]

have started to use Base for my little project. said before, but Base is simply awesome!:)just wondering if anyone has figured out how to document the Base-based code. JSDoc does not seem to foot the bill. for the moment, i am sticking with POD. better ideas?

  • Comment by: oak
  • Posted:

[…] class this link tutorial maybe will help you  A Base Class for JavaScript Inheritance […]

Hi Dean, I am still building a whole GUI framework on top of your Base class and loving it!! But I have a question. I found out that you don’t do the ‘init’ of a class if it already has a constructor….why?

snippet:

// single instance var object = constructor ? klass : _prototype; // class initialisation if (object.init instanceof Function) object.init();

TNX in advance

Maurice

  • Comment by: morriz
  • Posted:

@morriz – You are misinterpreting the code. The init method is for class initialisation only (see comment #26). The snippet you are referencing deals with the initialisation of classes and single instance objects.

  • Comment by: -dean
  • Posted:

@dean: take a look at the following snippet of code. it seems to me like Son.weird(); should still be a valid function.

var Pop = Base.extend({},{
   weird : function()
   {
      alert("Pa says `I like bacon'");
   }
});

var Son = Pop.extend();

Pop.weird(); //O.K.
Son.weird(); //Error: weird is undefined

I reckon classes should inherit instance AND static members. According to the ECMAScript 4 proposal, “static members are inherited from the superclass.” That proposal might also be helpful when defining a standard inheritance hack now, even though we’re not yet to Javascript 2.

  • Comment by: red daly
  • Posted:

@red – I thought about making static methods inherited but eventually decided against it. I’ll take a look at JS2 but I get the feeling the inheritance method there is slightly different.

  • Comment by: -dean
  • Posted:

Dean, thanx for explaining that (again, doh!)

But I have one other issue, which I assume must be related to my noobness:

I wish to use my eventmapping klass which has an interface like this:

EventMapper.addHandler(trigger, handler) // references to functions EventMapper.dispatch(obj, trigger)

but it seems that instantiations of objects use pointers to their original class functions and not copies of them, which makes my event dispatching fire all the time:(This is intrinsic to javascript’s prototype model I think, but I wish I could find a way to distinguish instances functions from each other….adding a reference to the instance itself leads to the same problem, ‘this’ is the same everywhere….drama

  • Comment by: morriz
  • Posted:

Wouldn’t be nice if you could just do

Vehicle={      
    wheels:2,      
    setWheels:function(x){this.wheels=x},
    getWheels:function(x){return this.wheels} 
}.classify();

Car={wheels:4}.classify().inherit(Vehicle);

// This will now return 4
myCar=new Car();
alert(myCar.getWheels());

I think this is a pretty clean implementation of inheritance, so I’ve written a small library to support this. Have a look at http://www.thomasfrank.se/classy_json.html

@Thomas – extending Object.prototype is verboten.

  • Comment by: -dean
  • Posted:

@Dean – extending Object.prototype is erlaubt

@Thomas – That’s an awful solution.

  • Comment by: -dean
  • Posted:

@Dean – I suspect you’re not using “awful” as a synonym to “great” here. There are a couple of other solutions to “remove” Object.prototype members from for-in-loops and if-in-statements, some you might consider more elegant, but none that I found as easy to apply as this one.

Kind of suspected you wouldn’t give up your point of view on this one anyway, since you were the first to congratulate Eric on his unfortunate verboten standpoint.

I would love to use your libary, but LGPL seems strange for Javascript, and I’m not quite sure how to interpret it. I wonder if there is a different license choice you could make that would make it easier to use.

  • Comment by: Chris Smoak
  • Posted:

@Chris – the next release will have an MIT license.

  • Comment by: -dean
  • Posted:

I’ve been using Base with much success recently. However, I’ve run into a vexing problem that I was hoping someone might be able to help solve.

In the following code I’ve set up a CustomEvent class that extends Base. Ideally, other classes will create events internally and allow others to subscribe to them. Not rocket science so far. However, if you run the code below you’ll get two alerts showing “1”, rather than a “1” for x and “0” for y, as I would have expected. It looks like both x and y are sharing the same listeners array internally.

Have I constructed my classes incorrectly? Am I missing something basic? Any help would be much appreciated.

var Util = {} //namespace
Util.Events = {} // namespace
Util.Events.CustomEvent = Base.extend({
	listeners: [],
	subscribe: function(listener) {
		this.listeners.push(listener);
	},
	fire: function(scope) {
		this.listeners.each(function(listener) {
			listener.apply(scope, arguments);
		});
	}
});

var x = new Util.Events.CustomEvent;
var y = new Util.Events.CustomEvent;

x.subscribe(function(){});
alert(x.listeners.length);
alert(y.listeners.length);

Thanks, Dean, for the change to the more friendly license. Any hints on when the next release might be?

Justin, I would suspect your problem is the array literal you assign to listeners in the class definition, which won’t be dup’ed properly by Base for the separate instances of CustomEvent. If you set the property in the constructor, instead, it should work as expected:

...
Util.Events.CustomEvent = Base.extend({
    constructor: function() {
        this.listeners = [];
    },
    ...

In this case, the constructor is executed for each instance, creating two different arrays, instead of creating just one array in the block that gets passed to Base.extend.

  • Comment by: Chris Smoak
  • Posted:

@Chris, thanks for your help. You are right about using a constructor. If I change the above code to

var Util = {} //namespace
Util.Events = {} // namespace
Util.Events.CustomEvent = Base.extend({
	listeners: null,
	constructor: function() {
		this.listeners = [];
	},
	subscribe: function(listener) {
		this.listeners.push(listener);
	},
	fire: function(scope) {
		this.listeners.each(function(listener) {
			listener.apply(scope, arguments);
		});
	}
});

var x = new Util.Events.CustomEvent;
var y = new Util.Events.CustomEvent;

x.subscribe(function(){});
alert(x.listeners.length);
alert(y.listeners.length);

I get the results I expected: x has 1 listener and y has 0.

I’m a little sketchy on why my original method didn’t work, though. Is this a bug or is this behavior by design? I fear that I’ve been instantiating fields outside of a constructor on many of my classes that extend Base. Any help would be much appreciated.

@Justin – there is no real sense of “class” in JavaScript. So when we define class/object properties we are merely creating an object literal. That is why you need to initialise object properties in the constructor function.

@Everyone – I have a lot of code to release surrounding Base. The first package I will release will extend the JavaScript language a little:

I want to get these classes right before releasing. If you want an advance look then send me an email. I cannot guarantee that the code I send you will work though. It would just be for viewing.

  • Comment by: -dean
  • Posted:

I’d love to take a look at the code.

/Thomas

The Dojo folks have a nice page explaining their subclassing system. Some interesting stuff regarding their mix-in (multiple inheritance) approach and how they handle constructors vs initializers.

  • Comment by: Mike Wilson
  • Posted:

I recently did a journey somewhat like yours, with a slightly different ending.

Function.prototype.inherits = function (baseClass)
{
    function Blank() {}
    this.base = Blank.prototype = baseClass.prototype;
    this.prototype = new Blank();
    this.prototype.constructor = this;
};

That’s the entirety of my solution. Sample code:

// ==== Ancestor ====

function Ancestor() {
    this.ancestorVar = 0;
    this.instances++;
}

Ancestor.prototype.instances = 0;  // class variable

Ancestor.prototype.toString = function() {
    return "Ancestor";
};

// ==== Parent ====

function Parent() {
    Parent.base.constructor.call(this);
    this.parentVar = 0;
}
Parent.inherits(Ancestor);

Parent.prototype.toString = function() {
    return "Parent";
};

// ==== Child ====

function Child() {
    Child.base.constructor.call(this);
    this.objectNumber = this.instances;
}
Child.inherits(Parent);

Child.prototype.toString = function() {
    var ancestor = Child.base.toString.call(this);
    return ancestor + "'s Child #" + this.objectNumber;
};

Yes, there’s still the prototype element, but I prefer to keep everything out in the open. Functions and class variables are equals here. Accessing overridden functions is a bit ugly, but again, nothing hidden.

Once you get over those two bits, I love the rest of it. No calls to the constructor during the prototyping phase. Very light on memory (no redundant copies of anything during prototyping, no unnecessary closures). No global functions, and no affecting Object.prototype. The syntax is easily understandable by most automated tools. And the only marginally-difficult function is four lines long.

Ah well. Just felt like sharing.:)

[…] Over the years a myriad of implementations have popped up to simplify JavaScript inheritance. Some of the well known ones are from Douglas Crockford, Kevin Lindsey and Dean Edwards. These are all fine implementations. They of course differ somewhat in their capabilities and complexity. […]

[…] There is basicly two things you need to learn. There is a base class called Base. to write your own class you call Base.extend with a hash that contains all the methods. To call a superclass version of the method you just call this.base. Its really simple and adds just enough to help you build better code without getting in the road. See also: Base, Another post about Base […]

“Proper” OO Inheritance for JavaScript … this is the subject of a post by juerg leny to the helma mailing list. Juerg and Hannes attemted (independendly) to improve an approach by Dean Edwards. Dean meantions a few goals: I want to easily create classes without the MyClass.prototype cr…

MOOTOOLS kommen Erst gestern hat mich Jens auf das Banner auf der Mad4Milk-Website aufmerksam gemacht. Das darafhin lange (und ausgesprochen witzige) spekulieren, darüber was diese Tools sein könnten, hätten wir uns schon kurz danach sparen können. Denn Valerio Pro

  • Trackback by: web output
  • Posted:

Mootools JavaScript Library Released Mootools JavaScript Library Released

[…] Si Prototype, script.aculo.us jQuery, MooFX, Dojo, Mochikit, Rico y las demás te parecían pocas librerías Javasript para elegir, los italianos de Mad4milk (los desarrolladores de MooFX, que a su vez sirvió de base para jQuery) acaban de lanzar MooTools, una pequeña librería que incluye los efectos de MooFX e incorpora las utilidades de Orientación a Objetos de Prototype, con mejoras introducidas por la clase Base.js de Dean Edwards. […]

[…] mootools implements a class inheritance scheme that is inspired by Dean Edwards’ wonderful Base class. Creating a class is similar to Prototype, but now you don’t ever have to think about the prototype object when you define the class: […]

Hi Dean,

Nice work. In your example above, I see you have:

Event.add(window, "unload", this.closeAll, this);

where is Event.add defined? I can’t seem to find it in prototype.js or base.

thanks Nick

  • Comment by: nickfox
  • Posted:

@nickfox – it is only an example.

  • Comment by: -dean
  • Posted:

I am using your base class and I create it like this and have an event where I capture clicks on a table and process them:

    var eip = new EditInPlace('tasktable');
    Event.observe($('tasktable'), 'click', eip.taskCatchIt);

In my class definition, I have a variable called editing and the method definition:

var EditInPlace = Base.extend({
    constructor: function(id) {
        this.id = id;
    },

    id: null,
    editing: false,

    taskCatchIt: function(e) {
	if (this.editing) return;
    }

This does not work, but if I do this:

    taskCatchIt: function(e) {
	if (eip.editing) return;
    }

it does work, but I cannot hardcode the object name into my code, is there a proper way of doing it?

thanks Nick

  • Comment by: nickfox
  • Posted:

Ok, I figured it out, I put the Event.observe into the constructor:

        Event.observe($(this.id), 'click', this.taskCatchIt.bind(this));

and it worked.

Dean, what blog software do you use, I really like the way this works.

thanks Nick

  • Comment by: nickfox
  • Posted:

@nickfox – I use a hacked version of WordPress with a comment preview/validation plugin (also hacked). The syntax highlighting module I wrote myself.

  • Comment by: -dean
  • Posted:

Hello,

This is my case for adding two lines to your already excellent Base.js. In re-reading this I see it has got rather long, but hopefully not tedious.

I’ve spent a while reading through Base.js and it certainly accomplishes the 6 points you set out in the introductory article. I however, would have added another requirement – that every constructor in the inheritance chain is called when instantiating an object. The constructor of a class generally does setting-up work that is essential for the other methods in that class to work. The constructor is particularly important in JavaScript since there is no formal language equivalent of member variables and initializer blocks, so the constructor is the only chance we have to ensure that member variables are created and appropriately initialized.

Take the following example:

var Animal = Base.extend({
	constructor: function(name) {
		this.name = name;
	},
	getName: function() {
		return this.name;
	}
});

var Mouse = Animal.extend({
	constructor: function(name, holeLocation) {
		alert("the mouse called '" + this.getName() + "' lives " + holeLocation);
	}
});

var m = new Mouse("squeek", "under the stairs");
// alerts: "the mouse called 'undefined' lives under the stairs"

In Base.js as it stands, ‘m’ is not a proper Animal, because Mouse.constructor forgets to call Animal.constructor, and therefore m.getName() is broken. The designers of Java realised this and enforced that the superclass constructor is called at the start of any constructor, so that the constructor can rely on properties of the superclass being correctly initialized. We are currently working on a very large JavaScript system in which this is a frequent problem.

Here is a slight modification to Base.js that accomplishes the same. Were it my library (and it isn’t :-)) it would be the default behaviour with no way to remove it. People can always take behaviour out of the constructor and put it into a static factory function if they don’t want it to be inherited by subclasses:

	// from Base.extend:
	// create the wrapper for the constructor function
	var _super = this;
	var klass = function() {
		_super.apply(this, arguments);
		if (!Base._prototyping) constructor.apply(this, arguments);
		this.constructor = klass;
	};

There are of course disadvantages to this – in particular, Mouse.constructor cannot alter the parameters being passed onto Animal.constructor. Since there is no simple way to discover if Mouse.constructor calles this.base(), if it does then Animal.constructor will be called twice:

var Mouse = Animal.extend({
	constructor: function(name, holeLocation) {
		this.base(name + 'mousie!'); // this calls Animal.constructor for the second time 
		alert("the mouse called '" + this.getName() + "' lives " + holeLocation);
	}
});

A small price to pay I would say. What are your thoughts?

Have a nice day…

Bernie

  • Comment by: Bernard Sumption
  • Posted:

@Bernie – Thanks for the suggestion but I think I prefer Base the way it is. You can already inherit the previous constructor function by calling this.base(). This is more flexible in that:

  • Comment by: -dean
  • Posted:

[…] Inanzitutto volevo qualcosa che mi rendesse facile la programmazione Object Oriented in Javascript visto che non è proprio così immediata (un po’ nello stile Perl). Avendo sentito parlare bene di Base.js ho deciso di provarla e devo dire che mi ha risparmiato un bel po’ di lavoro rendendo il codice molto più pulito. […]

Die MOOTOOLS haben jetzt ein Wiki Wie der MOOTOOLS-Entwickler Valerio Proietti in seinem Blog mad4milk schreibt, hat er zur Dokumentation seines JavaScript-Frameworks ein Wiki aufgesetzt. Mit der Befüllung desselbigen hat er ebenfalls schon begonnen.Herausgekommen sind hierbei bereits:G

  • Trackback by: web output
  • Posted:

[…] First off, of the half dozen or so requirements that Dean Edwards puts on his Base.js implementation I admittedly only agree with two of them – and you should see why at the end of this post. Those two are: I want to avoid calling a class’ constructor function during the prototyping phase I want to achieve the above without affecting Object.prototype […]

Pragmatic OOP in JavaScript Part 2 : To prototype or not to prototype My recent post on object orientation in JavaScript has resulted in some quite interesting comments. Good

[…] A Base Class for JavaScript Inheritance (tags: Javascript prototype oop) […]

[…] Inheritance has long been a pain in the side of Object-Oriented Javascript developers. Prototype tried hard with it’s initial offering of Object.prototype.extend, but ultimately fell back to the ugly Object.extend that’s created a bit of madness. However, MooTools uses a spinoff of Dean Edward’s Base.js. This fixes access to overridden methods and supports a nice clean syntax: […]

[…] תכ ות מכוון אובייקטים (OOP) כמעט מלא (עד איפה ש-JS מאפשר), תמיכה בהורשה, הסתרת מתודות, קריאה למתודות האב, קריאה לב אי האב וב אים. מה שבJS היה יחסית מסובך לעשות עד עתה (בספריית Prototype המימוש לא היה מלא כמו עכשיו). הכל תודות לדין אדוורדס ומחלקת ה-Base שלו. […]

[…] תמיכה בOOP – שדרוג הדרך שבה הספרייה יוצרת מחלקה לאופן שאותו Dean Edwards כתב במחלקת ה-Base שלו תוך כדי שמירה על קו ספט ה-Ruby’s way שקיים ב-Prototype. […]

Looks pretty interesting! Would be great if I get it to work on firecat. And I think LGPL is ok!;)

  • Comment by: David Fu
  • Posted:

[…] Of course it uses Prototype, it uses Scriptaculous effects.js and builder.js as well but I will try to make this dependancy optional later, and finally it uses Base.js to easily and nicely create OOP due to lake of simple tool in Prototype yet (they plan to integrate Base approach on v2 of Prototype). Actually scriptaculous effects.js is now optional. […]

I am trying to extend the Array object using Base. for example:

Base(Array); testA = Array.extend( { _message: null,

initialize: function(message) { this.base(message); this._message = message; },

showMessage: function() { alert(this._message); }

});

When I instantiate the object the showMessage() function is not a method of the object? Am I making a mistake, or can I not extend built-in objects?

  • Comment by: Shannon
  • Posted:

[…] Base++.js.zip — includes my custom Base++.js, diagram.html, and an example inheritance diagram and Javascript. Dean Edwards’ original Base.js page GraphViz […]

[…] The base2 core library is also quite useful in its own way. It includes things like my Base class and enumeration methods. I’ll document this library sometime in the future (it’s only little). For the time being I am only supporting the base2.DOM module and even then only if you are using the bind() method that I’ve demonstrated here. […]

[…] A Base Class for JavaScript Inheritance (tags: javascript inheritance) […]

I love Base.js – its great. Thanks so much for creating it. I’m using it with Mochikit and its a really good complimentary script.

Cheers

Guy

  • Comment by: Guy Thomas
  • Posted:

Works of FF but I cannot get it working with IE 7 , any advise?

  • Comment by: NikD
  • Posted:

Sorry ! i got it working … just changed the “language” to “Javascript1.3”

  • Comment by: NikD
  • Posted:

[…] A Base Class for JavaScript Inheritance […]

This looks interesting – and nicely explained. Has anyone benchmarked it? Do you know how it compares to using regular js prototyping (initial script loading that is).

I have a lot of code with inheritance etc, and trying to optimize so page load times shorten. I stumbled across this site looking for a way to stop constructors being called during the prototyping phase. They really add up when you have a large base of classes that leverage each other. But I suspect the overhead of this “Base class” approach, in passing objects and looping through them, will outweigh any benefits wrt load times. Anyone ?

P.S. Firebug’s console.time() and console.timeEnd() are super-handy at measuring script loading times. Maybe I’ll try measuring it when I find time.

Thanks for posting this.

  • Comment by: Glen
  • Posted:

Base is optimised for fast instantiation not for fast class building.

  • Comment by: -dean
  • Posted:

[…] Justin Palmer and Dean Edwards have already talked a lot about this, but I thought I’d take a stab at it. What we need is an easy way to create classes, create subclasses, and add properties and methods to classes. And, as Sam Stephenson mentions on his blog, we need it to be simple and backwards compatible. The current Prototype implementation of class creation follows: var Class = {   create: function(){ return function(){ return this.initialize.apply(this, arguments); } }   } […]

[…] Dags för mig och skriva en liten rad eller två. Eller fler. Allt kanske inte är helt relevant, men jag tänkte att det kunde vara kul med lite onödigt vetande också. Det bibliotek jag valt för Wobis heter alltså MooTools och har inspirerats av bland annat Prototype och Dean Edwards’ Base. MooTools var från grunden bara moo.fx, ett grymt litet effektbibliotek som krävde[1] just Prototype för att fungera. […]

[…] I had a hard time understanding basic classes in JavaScript and the tutorials I found all got way to bogged down in useless fluff, so I thought I’d put up this no-nonsense example of a JavaScript class. Expect a version using Base.js once I learn that way. […]

[…] http://dean.edwards.name/weblog/2006/03/base/ “I’ve created a JavaScript class (Base.js) that I hope eases the pain of JavaScript OO. It’s a simple class and extends the Object object by adding two instance methods and one class method.”Tags: javascript, oop, programming, inheritance, library, oo, api, class(del.icio.us history) if (typeof window.Delicious == “undefined”) window.Delicious = {}; Delicious.BLOGBADGE_MANUAL_MODE = true; […]

hi dean, i love your base.js. i got it working in mozilla very fine. but in ie6 i always get error-message: “my_object is undefined”.

the ie really doesn’t like this simple example. the mozilla doesn’t make any problem (even with “real”-code). is that known? although i don’t assume the fantastic base.js wasn’t written just only for mozilla?

greetings chris

  • Comment by: Chris
  • Posted:

@Chris – if you show me the code that is giving you trouble I’d be glad to help. You can mail me it to me using my contact form.

  • Comment by: -dean
  • Posted:

i tried to append some example-code, but i’m not allowed to paste it (although i wrap it into pre and the validator like it). so i pasted the code here: http://pastie.caboo.se/85313

greetings chris

  • Comment by: Chris
  • Posted:

@Chris – you are calling new foo() before you have defined foo.

  • Comment by: -dean
  • Posted:

maybe my pasting was misleading. i included the application.js in the header. so the class-declaration is available. so the first part of the example is located in the application.js (included js-file) and the part with “on the page” is following.

  • Comment by: Chris
  • Posted:

hi dean,

unfortunately still don’t get it running on ie. i really have no idea why. i assume base.js should work with ie? you also can write my email. i think you have it. i would be very thankful helping me (i made some effort with a class, when i realised this problem).

greetings chris

  • Comment by: Chris
  • Posted:

[…] Pretty nice. No VB and some decent OOP happening in ASP. It is however limited to this page but if I were to write a small framework or use something like Dean Edwards base and include it on each page of the project it is a, to me anyways, an exceptable compromise. […]

[…] Lisans MIT-style license. MooTools Telif Hakkı copyright © 2007 Valerio Proietti, http://mad4milk.net MooTools Hakkında -Class çok az bir kısmı Base.js’yi temel alır.http://dean.edwards.name/weblog/2006/03/base/ © 2006 Dean Edwards, Lisans http://creativecommons.org/licenses/LGPL/2.1/ -Birçok fonksiyon prototype.js den esinlenerek oluşturulmuştur. http://prototype.conio.net/ © 2005 Sam Stephenson sam@conio.net, MIT-style license -Belgelendirme Aaron Newton(aaron.newton@cnet.com) and Valerio Proietti tarafından yapılmıştır. […]

[…] Dean Edwards’ Base базовые классы и наследование в JavaScript. […]

Nice work Dean

I miss some functionallities though.

It would be nice to be able to get the base’s base function.
Something equivalent to: this.base.base()

Implement() is a good solution but you might want to be able to know if an object implements something. obj.implements(Bird) true/false

Animal –> Fish –> FlyingFish[implement(Bird)]
myFish instanceof Animal -> true
myFlyingFish instanceof Animal -> true
myFlyingFish instanceof Bird -> false
myFlyingFish.implements(Bird) -> true

And maybe there could be a solution for overloading ( not overriding ). You probably need to add som sort of test expression for the arguments when you overload a method. If the exression does not return true, use the original method as default.

Cat.overload(/methodname/, /testexpression/, /method/)
Cat.overload(eat, arguments.length>0, function(food){alert(…)})
Cat.eat() would not be the same as Cat.eat(mouse)

I’ll test it some more and see if I can come up with anything else that’s missing:-D

/Johan

I’ll test it some more and see if I can come up with anything else that’s missing

There is nothing “missing”. Base is a simple class to add inheritance to JavaScript. Nothing more. I’m not trying to turn JavaScript into a full OO language. There really is no need.

  • Comment by: -dean
  • Posted:

[…] Mootools mad4milk tarafından geliştirile dursun kökeninde farklı kullanıcıların scriptleri yatmaktadır ve bunlar optimize edilerek ortaya çıkmıştır.Örneğin core.js yani çekirdek scripti base.js adında ve Dean Edwards’a ait bir scriptten az da olsa yaralanmıştır bunun dışında prototype.js‘den çok esinlenlenmiştir.Şimdi ise daha da genişleyen bir kütüphane olması nedeniyle daha fazla optimize edilmiş scriptten yaralanmaktadır. […]

[…] Dean Edwards ist ein weiterer Name, den man sich merken sollte. Mit Base hat er eine wunderbare Vererbungsgrundklasse geschrieben, die schöne OO Vererbung ermöglicht und voraussichtlich auch in Prototype 2.0 enthalten sein wird. Ebenfalls einen Blick wert ist cssQuery, welches auch Abfragen im jQuery-Stil ermöglicht. […]

hi dean,

i used your base.js and i’m very happy, that you created it. i use it in rails (that means i also include prototype.js). in IE and gecko-browser all is fine. the only issue i have is in opera. not a bad one, but ugly. everytime a page is rendered the base.js calls an undefined rails-controller-action. nothing happens (so it’s not bad), but my logfiles are full of that ugly message (action not found etc…). when i exclude the base.js the opera does not this kind of unexplainable behaviour. but i really like the base.js…. so maybe you can explain me, how to prevent this opera-behaviour?

  • Comment by: Chris
  • Posted:

[…] In this post I will be discussing how one can achieve Class Hierarchy and Data Encapsulation in JScript. […]

[…] First off, it improves performance substantially over the initial release by inspecting method definitions to find out if they use this._super. If they don’t, they can be inserted straight into the class’ prototype without being wrapped in a _super-generating function. I believe Prototype and Base do something similar, though Inheritance seems not to. […]

[…] There is one design decision in JS.Class that sets it aside from all the other inheritance libraries I looked at (Prototype, Base and Inheritance). With all those libraries, super means “the previous version of this method in this class”, rather than “the current version of this method in the parent class”. Now, if you’ve just built a class by inheriting from a parent class and then overwriting some of its methods, those two definitions amount to the same thing. […]

[…] November 20, 2007 In early 2006 Dean Edwards began a little project called Base. This was he first attempt to ease the pain of developing Object Oriented JavaScript. I want a nice base class for JavaScript OO: […]

[…] In early 2006 Dean Edwards began a little project called Base. This was he first attempt to ease the pain of developing Object Oriented JavaScript. I want a nice base class for JavaScript OO: […]

[…] A mechanism for inheritance […]

[…] A mechanism for inheritance […]

[…] A while back I published my Base class for JavaScript inheritance. There have been a few more solutions to inheritance since then and most of the major JavaScript libraries contain an implementation of some kind. […]

Don’t feel unloved, Dean. |base| is an excellent choice for the name given that no name is going to be perfect for this situation. I’ve been using |getSuper| in Chiron, but there’s no question that it’s ugly. The only problem with |base| is that it implies that you’re actually getting *the* base instance (the eldest ancestor, nominally |Object|). Whatever; |base| is succinct, brief, and certainly good enough.

  • Comment by: Kris Kowal
  • Posted:

[…] Since we use Dean Edwards’ Base library for our inheritance the JSDoc out of the box wouldn’t work without commenting explicit method name and memberOf attribute – which, in my view, defeats the point. […]

Hello Dean. Sorry, I don’t speak English very well. JavaScript "like Java"

var ClassA = Class.create("ClassA",function(){
	var value = "value:A";
	this.getValue = function(){
		return value;
	};
	this.$$constructor = function(){
	};
});

var ClassB = Class.extend("ClassB",ClassA,function(){
   	var value = "value:B";
	this.getValue = function(){
		return value + this.$$super[0].getValue(); 
	};
	this.$$constructor = function(){
	};
});

var instB = new ClassB ( ); 
alert (instB.getValue ( )) ; // value:B value:A 

You can see more examples in JSimpleClass

Bye.

[…] Az osztályok hiánya javascriptben nem kifejezetten érzékelhető, mivel minden objektum használható class-ként. Bővebben erről Dean Edwards blogjáról tudhattok meg, én itt, ebben a sorozatban nem térek erre ki külön. Az Ext OOP éppen ezt a javascript tulajdonságot használja ki. […]

[…] Az osztályok hiánya javascriptben nem kifejezetten érzékelhető, mivel minden objektum használható class-ként. Bővebben erről Dean Edwards blogjáról tudhattok meg, én itt, ebben a sorozatban nem térek erre ki külön. Az Ext OOP éppen ezt a javascript tulajdonságot használja ki. […]

[…] Some recent experiments with Dean Edward’s excellent Base javascript library has given me an insight into how we can speed up the development of the typical user interface components that we are asked to include in our projects; ones such as tooltips , popups and draggable windows. […]

Dean, Outstanding result! Especially the base function. Without this to provide proper inheritance javascript objects would be pointless. Congrats

  • Comment by: Peter McGill
  • Posted:

[…] http://dean.edwards.name/weblog/2006/03/base/ “I’ve created a JavaScript class (Base.js) that I hope eases the pain of JavaScript OO. It’s a simple class and extends the Object object by adding two instance methods and one class method.” […]

[…] 类式继承:Douglas Crockford的模拟函数 Dean的Base库 […]

[…] * Class is slightly based on Base.js http://dean.edwards.name/weblog/2006/03/base/ © 2006 Dean Edwards, License http://creativecommons.org/licenses/LGPL/2.1/ * Some functions are inspired by those found in prototype.js http://prototype.conio.net/ © 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license * Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. […]

[…] * Class is slightly based on Base.js http://dean.edwards.name/weblog/2006/03/base/ © 2006 Dean Edwards, License http://creativecommons.org/licenses/LGPL/2.1/ * Some functions are inspired by those found in prototype.js http://prototype.conio.net/ © 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license * Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. […]

[…] In early 2006 Dean Edwards began a little project called Base. This was he first attempt to ease the pain of developing Object Oriented JavaScript. I want a nice base class for JavaScript OO: […]

Hi, I have tried an different techniques related to JavaScript inheritance subject. The code and the explanation are to long to post them here so if anyone is interested to take a look over it you can find it at http://www.dotnetcaffe.net under JavaScript category. Fell free to criticize the code in any way you want…just don’t flame :).

  • Comment by: M
  • Posted:

[…] Class ini tergantung dengan script saya terdahulu, yaitu Class FError dan Clone Array. Oh ya, hampir lupa tergantung pula dengan Base.js buah karya Dean Edward […]

[…] inheritance pattern to simplify subclassing (you could use a fancier one like Dean Edward’s Base, or manipulate prototypes […]

[…] понравились менее всего =): это реализации в Prototype.js и в Base2. В обоих способах нельзя вызвать “другой” метод […]

[…] A Base Class for JavaScript Inheritance – Dean Edwards […]

Interestingly I notice orders of magnitude difference in speed between your current version (1.1 and an older version 1.0.1) if you do not use the new keyword when creating objects.

I ran some speed differences between the two testing object creation:

for (var i=0; i<10000; i++)
{
	var cir = Circle(50,50,5);
}

Results:

Base version	1.0.1		1.1
Timings per browser (in ms)
Firefox 3.0.3		280		910
IE 7			640		844
Opera 9.52		60		250
Safai	3.1.2		125		313
Chrome			265		509
  • Comment by: ChrisB
  • Posted:

Brilliant resource you have on this site! Simply magnificent! I have now bookmarked this page and also subscribed to your RSS.

You are a great ‘teacher’

Evans http://www.jroller.com/evans

  • Comment by: Evans
  • Posted:

Dean, You enlightened me. Great thank you!

  • Comment by: Semion
  • Posted:

Dean,

I was trying to create a single instance class by copying your example (although I changed Math to Math2 since Math already exists) and I receive the following error:

constructor is null.

Has anyone else had this problem?

I tried creating my own object as well and had the same problem.

  • Comment by: Bryan Deemer
  • Posted:

Dean, the link to the Base.js file is pointing to your old .name domain.

  • Comment by: Scott McMillin
  • Posted:

[…] A Base Class for JavaScript Inheritance – Dean Edwards […]

i am no expert in javascript…

i am doing a video gallery with flowplayer flash file… it comes with a javascript. My mark-up shows these line:

$(function() {

// setup player $f(“player”, “swf/flowplayer-3.1.4.swf”, {

clip: {baseUrl: ‘http://blip.tv/file/get’}

// playlist plugin }).playlist(“#playlist”);

});

my problem is, i have my flv files and it doesn’t show in the player container since it has a base URL for the flv clips… i won’t use that URL… how can I override that?

  • Comment by: Roberto Mar
  • Posted:

[…] Base-Klasse von Dean Edwards kümmerte sich um […]

[…] Base […]

Hi Dean,

I did not find any mentions of the changes concerning “Single Instance” functionality in follow-ups to this post (I believe there were two of them since this original post). But it seems this special handling of the constructor: null which is described above was removed at some point along the way. And it did not make it into base2 variant either. At least currently the code does not produce “static class” as it is mentioned in some comment above, just ordinary class with instance members which cannot be instantiated because it throws an exception on attempt to create an instance.

  • Comment by: Alexei
  • Posted:

[…] proof of concept. A big change was needed and while I had considered using a small library like Dean Edward’s Base or John Resig’s Simple JavaScript Inheritance pattern to add class-based inheritance to […]

[…] that Base.js also supports class methods and Resig's code is a tiny bit shorter.Base.js: http://dean.edwards.name/weblog/…Simple JS Inheritance: http://ejohn.org/blog/simple-jav…Your code in either case ends up looking […]

[…] Don’t search any more: Dean Edwards: A Base Class for JavaScript Inheritance […]

[…] of the biggest advantages we’ve gained is by incorporating base.js. It’s been a major part of all of our mobile […]

[…] was invented. From Crock’s explanation on prototypal inheritance to Dean’s Base one and two, from Prototype’s Class to Mootool’s Class, and from debunking objects to […]

  • Pingback by: Klass
  • Posted:

I’m playing around with using this in the module pattern. Are there any drawbacks to doing the following?

Namespace.Class1 = (function() {
	var test = "test";

	function getTest() {
		console.log(test);
	}

	// reveal public/inheritable methods
	return Base.extend({
		getTest: getTest
	});
}());

Namespace.Class2 = (function() {
	var anotherTest = "anotherTest";

	function getAnotherTest() {
		console.log(anotherTest);
	}

        // inherit, override, reveal
	return Namespace.Class1.extend({
		getAnotherTest: getAnotherTest,

		// OVERRIDES
		getTest: function() {
			this.base();
			console.log("This is getTest override");
		}
	});
}());
  • Comment by: Brett
  • Posted:

[…] Base Class for JavaScript Inheritance ( http://dean.edwards.name/weblog/2006/03/base/ […]

[…] as small scripts (say less than 5kb of code) for handling very specific tasks from templating to inheritance to animation. With the common JavaScript frameworks increasing in size with every release people […]

[…] while I am well aware that the web is filled with various implementations of classical (i.e. class-based) object orientation in JavaScript, I can not help […]

I’ve just finished writing yet another class inheritance library called klass.js.

It supports public, protected and private methods, auto-creation of getters and setters, abstract classes and methods, final methods, static members, multiple inheritance and calls to super…

Curious to know what you think about it…

Some example syntax:

// Class definitions
var Animal = klass (function Animal(){
  _public (move, bite);
  var name;
  var _constructor = function(n){
    name = n
  };
  var move = function(meters){
    alert (name + ' moved ' + meters + 'm.')
  };
  var bite = function(){
    alert (name + ' bites!');
  };
});

var Snake = klass (function Snake(){
  _extends (Animal);
  var move = function(){
    alert ('Slithering');
    _super (5);
  };
  var bite = function(){
    alert(name + ' attacks with a venomous bite!');
   };
});

var Horse = klass (function Horse(){
  _extends (Animal);
  var move = function(){
    alert ('Galloping');
    _super (45);
  };
});

// Create some instances and call their methods
var sam = new Snake ('Sammy the Python');
var tom = new Horse ('Tommy the Palomino');
sam.move();
sam.bite();
tom.move();
tom.bite();

I’m trying to make private functions with Base.js, but they doesn’t work as expected (it’s obviously my fault!) ’cause I wrote something like:

var MyChild = MyParent.extend({
    /**
     * @constructor
     * @param params
     */
    constructor:function(params){
        this.base(params);
        function myPrivateFunction(name){
            return "Hello ".concat(name);
        }
    },
    myPublicFunction:function(name){
    	return myPrivateFunction(name);
    }
}

can you give an advice, please?

@Thomas I read your post it’s very interesting! I’ll try to use it asap and I’ll give you a feedback, thanks!

  • Comment by: Matteo Traina
  • Posted:

[…] to forcing JavaScript inheritance to behave like other, more natively-OOP languages, from Dean Edwards Base.js, to John Resig's take on it, to the approaches used by Prototype.js and MooTools (my personal […]

[…] base by dean edwards […]

[…] […]

[…] to develop a rather complex JavaScript tool. Although I need functionality like AJAX and preferably OOP-like inheritance, I do not want to decide on a library like jQuery or Prototype in favor of the user (here: website […]

[…] http://dean.edwards.name/weblog/2006/03/base/ […]

[…] because two properties can’t have the same name (color in the above example) under strict mode. While this seems like a glaring error, in some cases such as a mistake is not necessary easy to spot if the object literal is huge. This is a typical situation when you use various frameworks to implement an object using class-like construct. […]

[…] http://dean.edwards.name/weblog/2006/03/base/ […]

Great work you have here.:D Is there a way to make factory methods on the class?

  • Comment by: Vann
  • Posted:

Good work Dean.

Is there any way to define private variables? And can you explain a little about how to use implement method.

Thanks in advance:)

  • Comment by: young
  • Posted:

I tryed to make protected datas with Base.js. But it was necessary to modify Base.js slightly.

Base.js line 30, and after line 31.

// create the wrapper for the constructor function
//var constructor = proto.constructor.valueOf(); //-dean
var constructor = proto.constructor;
var klass = proto.constructor = function() {
	if (!Base._prototyping) {
		if (this._constructing || this.constructor == klass) { // instantiation
			this._constructing = true;
			var ret = constructor.apply(this, arguments);	// Catch the result.
			delete this._constructing;
			return ret;				// Return the result
		} else if (arguments[0] != null) { // casting
			return (arguments[0].extend || extend).call(arguments[0], proto);
		}
	}
};

Example: use protected datas.


function createValueAccessor(initial_value) {
	var currentValue = initial_value;
	return function(newValue) {
		if (arguments.length == 0) return currentValue;
		else return currentValue = newValue;
	};
}

var Foo = Base.extend({
	constructor: function() {

		// Define protected datas
		var protected_a = createValueAccessor(100);
		var protected_b = createValueAccessor(200);

		this.extend({
			printA: function() {
				alert(protected_a());
			},
			printB: function() {
				alert(protected_b());
			}
		});

		return {
			protected_a: protected_a,
			protected_b: protected_b
		};
	}
});

var Bar = Foo.extend({
	constructor: function() {
		var base = this.base();

		this.extend({
			print: function() {
				// Use protected datas
				alert(base.protected_a() + base.protected_b());
			}
		});
	}
});

var bar = new Bar();
bar.print();	// -> "300"

How about this?

  • Comment by: Kenta
  • Posted:

Hi Dean,

I have bookmarked this page as it is a bit of history. The modern JS framework MooTools is partly inspired by this post of yours from 2006.

Cheers, Thatch

  • Comment by: Thatch
  • Posted:

[…] as full documentation. I should also give a shout out to Dean Edwards for his JavaScript library Base, which is very awesome and I have used as the base for the […]

[…] part of it here (after, if you’re interested in finding out more, check out out his site for a few posts about […]

So is there no way to define a singleton using the Base code?

  • Comment by: Mike
  • Posted:

[…] A Base Class for JavaScript Inheritance:JS 大师 Dean Edwards 实现的 Base.js。 […]

[…] I would take a look at YUI, and at Dean Edward’s Base library: http://dean.edwards.name/weblog/2006/03/base/ […]

I have inherited code that uses your code. I have the job of unit testing the code. Everything works fine. What I am having trouble with is spying on the call this.base, as I have already tested the base code and don’t want to have to test it again for each method that calls this.base. Do you have any suggestions?

  • Comment by: Chris
  • Posted:

[…] Dean Edwards – A Base Class for JavaScript Inheritance http://dean.edwards.name/weblog/2006/03/base/ Prototype http://www.prototypejs.org/learn/class-inheritance Mootools […]

Comments are closed.