classical

Functional Classical Inheritance for Javascript

Classical ################## A simple cross-platform functional provider of classical inheritance for Javascript.

Including in your code

require('classical')

Classical methods (Class, Extend, Public, etc.) will be placed in the global scope and can be used anywhere in your code.

If you would prefer not to use Classical at the global level, you will need to set process.env.CLASSICAL_PROTECTGLOBALS to true, and then require classical in each class:

var Classical = require('classical')

You can then use the classical variables as Classical.Class, Classical.Extend, Classical.Public, etc.

In the browser, Classical requires require.js.

You must configure your requirejs to know where Classical's methods are located:

requirejs.config({
    paths : {
        Classical           : '/path/to/classical/index',
        Class               : '/path/to/classical/src/Class',
        Interface           : '/path/to/classical/src/Interface'
    },
    deps: ['Classical', 'Class', 'Interface']
});

You can then use Classical as a normal requirement:

define(function() {
    return Class(function() {});
});

If you would prefer Classical not put itself at the window level, you will need to set window.CLASSICAL_PROTECTGLOBALS to true before requiring Classical.

You must still configure Classical the same way; however, there are some differences when using Classical later:

define(['Classical'], function(Classical) {
    return Classical.Class(function() {});
});

Classical does not currently work in minified format

If you would like to use the minifed version of Classical, you must use a different requirejs config:

requirejs.config({
    paths : {
        Classical           : '/path/to/classical/index.min.js'
    },
    deps: ['Classical']
}

Classical does not currently work in minified format

You can also use the minified version of Classical without affecting the window. This is done the same way as before, using the configuration for the minfied version.

Examples

require('classical');
 
var Mammal = Class(function() {
    this.name                           = Protected(null);
 
    this.constructor = Public(function(name) {
        this.name                       = name;
    });
 
    this.speak = Public(function(text) {
        console.log('%s says, "%s"', this.name, text);
    });
});
var Dog = Extend(Mammal, function() {
    this.breed                          = Protected(null);
 
    this.constructor = Public(function(namebreed) {
        this.breed                      = breed;
    });
 
    this.speak = Public(function() {
        this._super.speak('Woof!');
    });
});
var Spot = new Dog('Spot', 'Dalmation');
Spot.speak(); // Outputs: 'Spot says, "Woof!"' to the console. 

API

Defines a public member for a class.

member The definition of the member. This member will be publically available for all instances of the class and its children.

PublicMember A public member

this.foo = Public(function() {
    return 'foo';
});

Defines a protected member for a class.

member The definition of the member. This member will be privately available for all instances of the class and its children.

ProtectedMember A protected member

this.foo = Protected(function() {
    return 'foo';
});

Defines a private member for a class.

member The definition of the member. This member will be privately available for all instances of the class, but will be unavailable to its children.

PrivateMember A private member

this.foo = Private(function() {
    return 'foo';
});

Defines a new Class.

fn The definition of the class, represented as a function.

Class A factory to create instances of the class (using the new keyword)

var Foo = Class(function() {
    this.foo = Protected(function() {
        return 'foo';
    });
    
    this.bar = Public(function() {
        return this.foo();
    });
});
var n   = new Foo;
console.log(n.foo()); // => 'foo' 

Extends an existing Classical or non-Classical class.

ancestor The non-Classical class to inherit from. fn The definition of the class, represented as a function.

var Baz = Inherit(require('event').EventEmitter, function() {
    this.constructor = Public(function() {
        this.on('baz', this.qux);
    });
 
    this.baz = Public(function() {
        this.emit('baz');
    });
 
    this.qux = Private(function() {
        console.log('foo');
    });
});
var n   = new Baz;
n.baz(); // => 'foo' 

Creates a new interface to be implemented.

fn The definition of the interface, represented as a function.

var Squee = Interface(function() {
    this.moog = Public(function(ap) {}); // A public method with one argument. 
    this.dar = Protected(Class.BOOLEAN); // A protected boolean 
    this.han = Public(Class.INT); // A public integer 
    this.mik = Private(Class.STRING); // A private string 
});

Implements interfaces as a classical class.

interfaces An interface (or several interfaces as an array). fn The definition of the implementing class, represented as a function.

var Nop = Implement(Squee, function() {
    this.moog = Public(function(ap) {
        return Util.format(this.mik, ap, this.han, ap + this.han);
    });
 
    this.dar = Protected(true);
    this.han = Public(4);
    this.mik = Private("%s + %s = %s");
});