jQsimple-class About Documentation Bugs Support git repository Download


NAME

jqsimple-class.js - a simple class-declaration for JavaScript


SYNOPSIS

jClass({
_constructor: function() { initialization stuff },
_destructor: function () { destruction stuff },
method1: function () { },
method2: function () {}
});
jClass.extend(existing, {
_constructor: function () { meh },
method1: function () { },
method2: function () { }
});
jClass.extendS(existing, {
_constructor: function () { meh },
method1: function () { },
method2: function () { }
});


DESCRIPTION

jqsimple-class is a simple class-declaration for JavaScript. It allows you to easily declare classes, inherit from other classes and lets you have constructors inline with your class declaration.

The basic syntax is simple:

var obj = jClass({
_constructor: function() { initialization stuff },
method1: function () { },
method2: function () {}
});

This makes a new class called 'obj', with the constructor defined, and the methods defined. The constructor will be called when 'new obj' is called.

You can also extend existing classes, as long as those classes are also using jqsimple-class. The syntax for this is:

var extendedObj = jClass.extend(obj, {
_constructor: function () { my init stuff },
method3 : function () { }
});

Now extendedObj is a class that inherits from obj. When 'new extendedObj' is called the constructor defined for 'extendedObj' is executed first, then the contructor for obj is executed.

If you want to inherit a class, but not call its constructor (or any inherited constructors further up the chain), use extendS instead, the result is the same with the exception of the constructor:

var extendedObj = jClass.extendS(obj, {
_constructor: function () { my init stuff },
method3 : function () { }
});


METHODS

To build classes

jClass({})

This is the basic class building function. It will build a class and return its constructing function. Basic use is: var myClass = jClass({}). Then you can create instances of myClass by running var myInstance = new myClass().

The JavaScript hash/object you supply to this method is just like any other, with the exception of the fact that if it has an entry named '_constructor', then that will be used as the constructor for the class instance, and it will recieve all the parameters that is supplied when running new myClass(). This means that if you have a constructor with the signature (debug) and a user runs new myClass(true) then the constructor will recieve the value true for the parameter debug. See jClass.extend and jClass.extendS for information about inheritance and constructors.

jClass.extend(parent, {})

This is a function that builds a class that inherits another class (which must also have been declared using jqsimple-class). It will inherit all methods of parent, override any methods that exist both in the parent and child and the constructor for parent will be called when constructing the object. See the section Constructors, destructors and inheritance for more information on constructors and destructors.

You can also inherit multiple classes, the syntax for that is: jClass.extend([ parent1, parent2 ], {}). See the section titled Inheritance resolution order for information about the resolution order.

See also the .jClass.inlineExtend method available on classes, and jClass.extendS.

jClass.extendS(parent, {})

This works exactly like jClass.extend, with the exception that this will not call constructors or destructors further up the chain. Only a single constructor and destructor will be executed, and that is the one defined in the object that is inheriting (the child). If that does not have any constructor/destructor, then no constructor/destructor will be executed.

As with jClass.extend() You can also inherit multiple classes without inheriting their constructors or destructors, the syntax for that is: jClass.extendS([ parent1, parent2 ], {}). See the section titled Inheritance resolution order for information about the resolution order.

jClass.virtual({})

This works like jClass({}), but creates a virtual class rather than a proper class. The difference is that a virtual class can not be instantiated, but it can be extended (and the resulting object can be instantiated as per usual). This is useful for writing base classes that does nothing useful unless they are extended as part of another class.

It is not possible to create virtual classes that extend other classes, they can only act as base classes extended by others. A virtual class can include a constructor and destructor just like normal classes.

On classes and object instances

When you create a class using jqsimple-class, any resulting object AND class will inherit a .jClass. namespace from jqsimple-class (and .jClass is therefore reserved for internal use). The methods available depends on if you are running them on the class itself, or an instance (an instance being the one you get from "new myClass" while the class itself is the one returned from jClass() and similar functions).

On both

.jClass.version

The version number of the jqsimple-class library in use.

On classes and virtual classes

.jClass.inlineExtend( {} )

inlineExtend allows you to add methods to a class without having to create a whole new class that extends the parent, essentially plugging your new methods into the parent. This has a few (delibarate) limitations: 1. You can't add or override a constructor 2. You can't replace existing methods

Example: myClass.jClass.inlineExtend({ method4: function () { } });

Any new instances of 'myClass' will now have the method4 method available.

You can also use inlineExtend to add methods from virtual classes, the same restrictions apply.

inlineExtend always returns .jClass, so it is possible to chain multiple inlineExtend calls after each other. Example:

myClass.jClass.inlineExtend(virtualClass1).inlineExtend(virtualClass2);

On object instances

The namespace .jClass. is reserved for future use.

.destroy()

Calls any destructors defined for the object, then completely destroys the instance of the object it is called on (removing all attributes and methods, only leaving behind an empty object equivalent to {}).


CONSTRUCTORS AND DESTRUCTORS

The _constructor is the method called when instantiating an object. It recieves all parameters supplied.

The _destructor is the method called when a user runs obj.destroy() (but not when the JS garbage collector removes it). It takes no parameters and should handle any action you want to take when a user decides to explicitly destroy an object.

Both the constructor and destructor are optional. If you don't need them, simply omit them from the class definition. Both construction and obj.destroy() will work just fine without them.

Constructors, destructors and inheritance

When using jClass.extend (not jClass.extendS), all constructors and destructors are inherited. The highest level constructor/destructor is called first, followed by the next one in the chain and so on all the way down. All constructors recieve all construction parameters supplied. Therefore it is a good idea to use key-value hashes/objects as the sole parameter, rather than named positional parameters, so that it is possible to supply useful values to all constructors, if that is needed.


INHERITANCE RESOLUTION ORDER

The inheritance resolution order used by jqsimple-class is rather simplistic, but will work very well in all but the most complex cases. Consider the traditional diamond inheritance pattern:

<A>
/   \
<B>   <C>
\   /
<D>

Here A inherits from B and C, and both B and C inherits D. Stupid resolution would end up with the chain A-B-D-C-D or A-B-D-C. jqsimple-class will resolve this to A-B-C-D.

The inheritance definition expressed in JS code with jClass:

var D = jClass({});
var B = jClass.extend(D,{});
var C = jClass.extend(D,{});
var A = jClass.extend([B,C], {});

Algorithm

The algorithm for it is simple: once all of the classes to inherit has been found, it will go through all of them, and each time it finds a class that has been inherited twice it will push that to the back of the chain. Here's an example of how it would resolve the above diamond pattern:

1. A       - base
2. AB      - inherited B
3. ABD     - B inherited D
4. ABDC    - A inherited C
5. ABCD    - C also inherited D, but D was originally in front of C in the chain
and its entry was thus pushed back to behind C


COMMONJS MODULE

Using the jQsimple-class CommonJS module is simple. Put the commonjs build of jQsimple-class somewhere in your module include path as jqsimple-class.js.

Then load jQsimple-class:

var jClass = require('jqsimple-class').jClass;

From there on you can use jClass as normal.


EXAMPLES

Building a simple class
var myClass = jClass({
_constructor: function ()
{
this.log('Yay');
},
log: function(msg)
{
console.log(msg);
}
});
var myInstance = new myClass(); // Logs 'Yay' to the console
myInstance.log('Hooray');       // Logs 'Hooray' to the console
Extending a simple class

This overrides the log method of the above class to be a bit smarter

var myBetterClass = jClass.extend(myClass, {
enableLog: true,
_constructor: function(enableLog)
{
this.enableLog = enableLog;
},
log: function (msg)
{
if(this.enableLog && console && console.log)
{
console.log(msg);
}
}
});
var myInstance = new myClass(true); // Logs 'Yay' to the console, if it is present
var myInstance2 = new myClass();    // Does not log anything
Extending a simple class and removing the constructor

This becomes myClass without any constructor, so it does not run log() on load. var mySilentClass = jClass.extendS(myClass, {}); var mySilentInstance = new mySilentClass(); // Does not log anything

Adding methods to an existing class

This will add the method stupidLog() to the existing myBetterClass class. This only has effect on new instances.

myBetterClass.jClass.inlineExtend({
stupidLog: function (msg)
{
console.log(msg);
}
});
Extending multiple classes
var myUtils = jClass.virtual({
utilMeth: function () { }
});
var myUI = jClass.virtual({
showMessage: function () { }
});
var myClass = jClass.extend([myUtils,myUI],{
_constructor: function ()
{
this.showMessage(this.utilMeth('Hi'));
}});


AUTHOR

Eskild Hustvedt, <code@zerodogg.org>


LICENSE AND COPYRIGHT

Copyright (C) 2010 by Eskild Hustvedt

This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Projects dontreadthecomments fcgim GoldenPod gpgpwd MagicPO Migraine Log mussort Pleiar.no rotcelloc wwine Show more