This is a Walktrough of Evan Byrne's Class.js ( http://www.evanbyrne.com/article/class.js ). I comment the Code using //!. Please think of this walktrough as a help to avoid these mistakes in the future, not as an insult to the coder.
/*
* Class.js - Providing class structure for javascript
* Licensed under the General Public License (http://www.gnu.org/licenses/gpl.html)
* Copyright 2010 Evan Byrne (http://www.evanbyrne.com/article/class.js)
*/
Class.js, wow, that's creative. Ok, I admit my project names are shitty, too. :(
function Class(obj,args)
{ //! Opening curly braces are placed at the end of the line before by convention in JavaScript.
for(key in ClassFn) //! key is undefined. Simply enter a var here.
{
this[key] = ClassFn[key];
}
for(key in obj)
{ //! All these for-in loops are unfilterd. Beware! http://www.yuiblog.com/blog/2006/09/26/for-in-intrigue/
this[key] = obj[key];
}
if(typeof(this.construct) == "function") //! construct is a weird name. It has nothing to do with a
{ //! constructor at all. How 'bout calling it "initialize" or "init"?
this.construct.apply(this,args);
}
}
ClassFn = { //! "ClassFn" sounds like a function but is an object.
/*
* Class.js Merge Method
* Copyright 2010 Evan Byrne (http://www.evanbyrne.com/article/class.js)
*/
//! Inline copyright notices?!
merge:function(obj){
for(key in obj)
{
this[key] = obj[key];
}
}
};
/*
* Class.js Extend Function
* Copyright 2010 Evan Byrne (http://www.evanbyrne.com/article/class.js)
*/
function Extend(obj1,obj2){ //! By convention only Classes should begin with a capital letter. This applies both to JavaScript as well as Java.
var o = obj2; //! What's the point of this?
for(key in obj1)
{
o[key] = obj1[key]; //! So you extend the second argument with the first one. I think the other way round feels more natural.
}
return o; //! Finally some cascading!
}
In total you create 3 global variables. Oh, wait. key becomes a global variable, too( in ES 3), because you didn't define it. 4 global variables seems like a waste to me.
var e = new Class(One);
e.set('Hello, World!');
e.get();
Class totally relies on the new operator. I think this is rather dangerous.
Let's have another look at the first line of the Example. You might read the code as: "e is a new class as defined in One". But in reality it is: "create a new empty object and copy all properties of One onto it."
Last but not least: Performance!
All these for-in loops are super slow. Even worse, the create a memory issue. Instead of using prototypes, which are just one internal pointer, you have one reference per property per object. That may sum up to a lot of bytes.
So that's that.
Other options:
ES 5
http://code.google.com/p/es-lab/wiki/Traits
http://webreflection.blogspot.com/2010/01/es5-es5-classes-as-descriptor-objects.html
http://github.com/Kambfhase/Din
ES 3
http://javascript.crockford.com/prototypal.html
http://jsclass.jcoglan.com/
http://ejohn.org/blog/simple-javascript-inheritance/
http://github.com/tobeytailor/def.js
http://mootools.net/docs/core/Class/Class
http://github.com/visionmedia/class.js/
MfG Hase