I no longer use class helpers. I would encourage using ES6 classes if you feel the need to emulate classical OO patterns.
A minimal class/mixin utility for JavaScript (ES5+), focusing on performance, node compatibility, and composition over inheritance.
This tool is best used with NodeJS. You can install it like so:
npm install klasse
Inspired by MooTools and jsOOP, the syntax is simple and readable:
var Class = require('klasse');
var MyClass = new Class({
//Optional base class to extend from
Extends: BaseClass,
//Optional array of mixins
Mixins: [ myMixins ],
initialize:
function MyClass() {
this.prop = "foo";
}
});
Keywords:
Extends
: Optional. Specifies the base class for prototype chain.Mixins
: Optional. Can be an array of mixins, or just a single mixin. A mixin is an object or Class which defines methods, properties, and so forth to be added directly to a class prototype.initialize
: Optional. The constructor method, generally a named function for clearer debugging. If not specified, and a base class is given to Extends
, the constructor will default to calling the base class constructor. Otherwise, an empty constructor will be used.Encourages best performance in a number of ways:
initialize
. This is more ideal for V8 optimizations (hidden classes).Class
constructor, it will beHere is a Vector example, where we reduce duplicate code but favour composition rather than inheritance. Inheritance (i.e. Vector3 extends Vector2) would lead to unnecessary lookups on the prototype chain.
var Class = require('klasse');
//A lightweight mixin which contains functions, properties, etc
//to be placed on the prototype.
var mixins = {
length: function() {
return Math.sqrt(this.lengthSq());
}
};
var Vector2 = new Class({
//Mixin the length. This accepts an array of mixins
//(lightweight objects, or a new Class) or you can
//just specify a single mixin.
Mixins: mixins,
//We use named functions for the constructor, which
//leads to nicer console logs on Chrome.
initialize:
function Vector2(x, y) {
this.x = x || 0;
this.y = y || 0;
},
lengthSq: function() {
var x = this.x,
y = this.y;
return ( x * x + y * y );
}
});
var Vector3 = new Class({
Mixins: mixins,
initialize:
function Vector3(x, y, z) {
//We can call the constructor like so
Vector2.call(this, x, y);
this.z = z || 0;
},
lengthSq: function() {
var x = this.x,
y = this.y,
z = this.z;
return (x * x + y * y + z + z);
}
});
If an object in the class definition or a mixin has get
and/or set
functions, then we assume its a property. It looks like this:
var Person = new Class({
initialize:
function Person(age) {
this._age = age || 0;
},
/** The 'age' property. */
age: {
get: function() {
return this._age;
},
set: function(value) {
if (value < 0)
throw new Error("age must be positive");
this._age = value;
}
}
});
var p = new Person(12);
p.age += 2; //increases age
console.log(p.age); //prints 14
p.age = -1; //throws error
Simplified properties are enumerable
and configurable
by default, unless otherwise specified. See below.
A property which has configurable
set to false will be considered final. Trying to Extend or Mixin and override such a property will throw an error. You can skip these errors by setting the Class.ignoreFinals
flag to true
before creating new classes. Then, only the first instance of that property will be included in your new Class.
You can grab the UMD file from the build
package, which is namespaced to klasse
. So your code might look like this:
var MyClass = new klasse.Class({
...
});
To build, install the necessary command-line tools:
npm install uglify-js yuidocjs browserify -g
Then run the build script from the project directory:
npm run build
BSD-2-Clause