79652a1120 | ||
---|---|---|
doc | ||
lib | ||
test | ||
tools | ||
.gitignore | ||
LICENSE | ||
Makefile | ||
README.md | ||
index.js | ||
package.json |
README.md
ease.js
ease.js is a basic collection of CommonJS modules intended to "ease" the transition into JavaScript from other Object-Oriented languages. It provides an intuitive means of achieving classical inheritance and has planned support traits/mixins.
Current support includes:
- Simple and intuitive class definitions
- Classical inheritance
- Abstract classes and methods
- Interfaces
- Visibility (public, protected and private members)
- Static, constant and final members
While the current focus of the project is Object-Oriented design, it is likely that ease.js will expand to other paradigms in the future.
This project is still under development. Please read the manual for more information.
Full Documentation
Full documentation is available at the following URL:
http://easejs.org/manual/ (Multiple Pages)
http://easejs.org/manual.html (Single Page)
Why ease.js?
There are already plenty of other means of achieving each of this project's goals, so what's the point of ease.js? The aim of the project is to provide a lightweight library in a CommonJS format which also addresses ES5 issues and is an all-inclusive solution to OO techniques. It satisfies primarily a personal itch.
How to Use
Please note that, as the project is under active development, the API may change until the first release.
ease.js uses the CommonJS module format. In the examples below, Node.js is used.
Defining Classes
The constructor is provided as the __construct()
method (influenced by
PHP).
var Class = require( 'easejs' ).Class;
// anonymous class definition
var Dog = Class(
{
'private _name': '',
'public __construct': function( name )
{
this._name = name;
},
'public bark': function()
{
console.log( 'Woof!' );
},
'public getName': function()
{
return this._name;
}
});
The above creates an anonymous class and stores it in the variable Dog
. You
have the option of naming class in order to provide more useful error messages
and toString() output:
var Dog = Class( 'Dog',
{
// ...
});
Extending Classes
Classes may inherit from one-another. If the supertype was created using
Class.extend()
, a convenience extend()
method has been added to it. Classes
that were not created via Class.extend()
can still be extended by passing it
as the first argument to Class.extend()
.
Multiple inheritance is not supported. ease.js is very generous with the options it provides to developers as alternatives, so pick whichever flavor your are most comfortable with: interfaces, traits or mixins. Multiple inheritance will not be added in the future due to problems which have been addressed by interfaces and traits.
Note that traits and mixins are not yet available. They are planned features and will be available in the future.
var SubFoo = Foo.extend(
{
'public anotherMethod': function()
{
},
});
// if Foo was not created via Class.extend(), this option may be used (has
// the same effect as above, even if Foo was created using Class.extend())
var SubFoo = Class.extend( Foo,
{
'public anotherMethod': function()
{
},
});
Abstract Classes
Abstract classes require that their subtypes implement certain methods. They
cannot be instantiated. Classes are considered to be abstract if they contain
one or more abstract methods and are declared using AbstractClass
rather than
Class
. If a class contains abstract methods but is not declared abstract, an
error will result. Similarily, if a class is declared to be abstract and
contains no abstract methods, an error will be thrown.
var AbstractClass = require( 'easejs' ).AbstractClass;
var AbstractFoo = AbstractClass(
{
// a function may be provided if you wish the subtypes to implement a
// certain number of arguments
'abstract public fooBar': [ 'arg' ],
// alternatively, you needn't supply implementation details
'abstract public fooBar2': [],
});
If the abstract method provides implementation details (as shown by
fooBar()
, subtypes must implement at least that many arguments or an exception
will be thrown. This ensures consistency between supertypes and their subtypes.
Abstract classes can be extended from just as an other class. In order for its subtype to be instantiated, it must provide concrete implementations of each abstract method. If any methods are left as abstract, then the subtype too will be considered abstract and must be declared as such.
// can be instantiated because concrete methods are supplied for both
// abstract methods
var ConcreteFoo = Class.extend( AbstractFoo,
{
'public fooBar': function( arg )
{
},
'public fooBar2': function()
{
},
});
// cannot be instantiated because one abstract method remains
var StillAbstractFoo = AbstractClass.extend( AbstractFoo,
{
'public fooBar': function( arg )
{
},
});
Interfaces
Interfaces can be declared in a very similar manner to classes. All members of an interface must be declared as abstract.
var MyType = Interface(
{
'abstract public foo': []
});
To implement an interface, use the implement()
class method:
var ConcreteType = Class.implement( MyType ).extend(
{
'public foo': function() {}
});
Note that, if a concrete implementation for each method is not provided, the implementing type must be declared abstract.
Use of Reserved Words
Though JavaScript doesn't currently implement classes, interfaces, etc, it does reserve the keywords. In an effort to ensure that ease.js will not clash, the following precautions are taken:
Class
is used with a capital 'C'Interface
is used with a capital 'I'- Reserved keywords are quoted when used (e.g. in property strings)