|
Project Information
Featured
Downloads
|
Classical is a (rather experimental) implementation of classical inheritance in JavaScript, as an alternative to its native prototypical inheritance. Classical adopts the familiar model of classes, public and private scopes, inheritance, and getters and setters seen in other OO-languages, with good cross-browser compatibility. Classical currently works with Firefox 2+, Safari 3+, and (yes!) Internet Explorer 6+. A rough technical demo is available here. UsageInclude 'classical.js' in your web application. Classes are created in the global scope with a call to the Class constructor: Class('Fruit', {
'seeds': 0,
'eat': function () {
console.log("The fruit has been eaten!");
}
});This can then be constructed conventionally: var fruit = new Fruit(); Note that all class properties and methods must be explicitly defined (objects aren't expando). Additionally, classes are declared in the global scope, regardless of in which scope they are declared. Functions should be defined inline in the Class constructor and not by variable reference (such as {'aMethod': somePredefinedFunction}). Constructors and CastsConstructors are made using a function named [constructor]: '[constructor]': function (arg1, arg2) {
// ...
}Casts (such as Fruit(someObject), without the new operator) can also be allowed using a function named [cast]: '[cast]': function (obj) {
// ...
}Casts operate just like constructors, in that they create an object which you can access by the this operator or scoped properties. Private and Public ScopeClassical re-evaluates all methods to add implicit class scope. This also means you can explicitly define private and public properties by adding the prefix public (by default) or private: 'private value_': 42,
'private addToValue': function (val) {
value_ += val; // note that value_ refers to object scope!
},
'public incrementValue': function () {
addToValue(1); // same with addToValue
}Only internal functions would be able to see the value_ and addToValue properties, whereas incrementValue would be publicly accessible by the object. Also note that the addToValue and incrementValue functions can seamlessly reference (and set) public and private properties and methods. Getters and SettersTo implement getters and setters, prefix the variable name with 'get' or 'set': 'private value_': 42,
'public get value': function () { return value_; },
'public set value': function (newVal) { value_ = newVal; }Getters and setters can be private or public. InheritanceSingle-class inheritance can be enabled by passing an existing class as a third parameter to the Class constructor: Class('Fruit', {
'seeds': 42
});
Class('Apple', {
'pies': 9
}, Fruit);Apple will inherit all the properties and methods of its parent (for instance, a new Apple will have a property seeds). An overridden method can also access its super method by using the uber() function (also works in the constructor and cast magic functions): Class('Fruit', {
'[constructor]': function () {
console.log("Creating a Fruit");
},
'ripen': function (taste) {
console.log("Ripening a Fruit. It tastes " + taste);
}
});
Class('Apple', {
'[constructor]': function () {
console.log("Creating an Apple");
uber();
},
'ripen': function (taste) {
console.log("Ripening an Apple. It tastes " + taste);
uber(taste);
}
});The following code: var apple = new Apple();
apple.ripen('good!');Would output the following: Creating an Apple Creating a Fruit Ripening an Apple. It tastes good! Ripening a Fruit. It tastes good! Type CheckingAn object can be verified to belong to a class using the class's hasInstance function: Class('Fruit', {});
Class('Apple', {}, Fruit);
var fruit = new Fruit();
var apple = new Apple();
Fruit.hasInstance(fruit); // true
Apple.hasInstance(fruit); // false
Fruit.hasInstance(apple); // true
Apple.hasInstance(apple); // true
Fruit.hasInstance(aNonClassObject); // falseLimitationsThere are some important things to keep in mind:
The following are not really limitations, but should be mentioned:
CreditThanks goes out to Alex of Dojo for his functional demo of getters and setters for IE (the inspiration for this) and Douglas Crockford's Classical Inheritance in JavaScript (even if I managed to blaspheme everything of which it speaks). |