2010-11-11 00:12:59 -05:00
|
|
|
# ease.js
|
|
|
|
|
2011-09-21 12:01:00 -04:00
|
|
|
ease.js is a 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.
|
2010-11-15 12:11:11 -05:00
|
|
|
|
|
|
|
Current support includes:
|
|
|
|
|
2011-03-09 13:02:59 -05:00
|
|
|
* Simple and intuitive class definitions
|
2010-11-15 12:11:11 -05:00
|
|
|
* Classical inheritance
|
|
|
|
* Abstract classes and methods
|
2011-01-11 18:30:32 -05:00
|
|
|
* Interfaces
|
2011-03-09 13:02:59 -05:00
|
|
|
* Visibility (public, protected and private members)
|
2011-09-20 17:16:27 -04:00
|
|
|
* Static, constant and final members (**important: see virtual/master branch**)
|
2011-03-09 13:02:59 -05:00
|
|
|
|
|
|
|
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.
|
2010-11-11 00:12:59 -05:00
|
|
|
|
2011-04-04 07:42:14 -04:00
|
|
|
**This project is still under development. Please read the manual for more
|
|
|
|
information.**
|
2010-11-11 00:12:59 -05:00
|
|
|
|
2011-09-21 12:01:00 -04:00
|
|
|
**Release/npm Note:** The first release of ease.js (and subsequently,
|
|
|
|
availability on npm) will come once the features are solidified and committed
|
|
|
|
to. This is to ensure adoption is not stifled by design alterations. Version
|
|
|
|
0.1.0 release is near; please see the
|
|
|
|
[v0.1.0 roadmap](http://easejs.org/bugs/roadmap_page.php?version_id=1) for
|
|
|
|
out-standing issues.
|
|
|
|
|
2011-06-07 19:55:45 -04:00
|
|
|
## Full Documentation
|
|
|
|
Full documentation is available at the following URL:
|
|
|
|
|
|
|
|
http://easejs.org/manual/ (Multiple Pages)
|
|
|
|
|
|
|
|
http://easejs.org/manual.html (Single Page)
|
|
|
|
|
2011-08-27 16:24:37 -04:00
|
|
|
## Bug Reports / Feature Requests
|
|
|
|
Please direct bug reports and feature requests to the bug tracker located at
|
|
|
|
http://easejs.org/bugs/
|
|
|
|
|
2010-11-11 00:12:59 -05:00
|
|
|
## Why ease.js?
|
2011-09-21 12:01:00 -04:00
|
|
|
There are already a number of libraries/frameworks that permit basic classical
|
|
|
|
Object-Oriented development, so why ease.js? While many of the existing
|
|
|
|
solutions certainly provide viable solutions, they are largely incomplete. Until
|
|
|
|
the appearance of ECMAScript 5, many of the features enjoyed by classical OO
|
|
|
|
developers were elusive to JavaScript. The aim of this project is to provide an
|
|
|
|
intuitive framework in a CommonJS format which also addresses ES5 issues and is
|
|
|
|
an all-inclusive solution to OO techniques.
|
|
|
|
|
|
|
|
ECMAScript reserves certain keywords that hint at classical OO in future
|
|
|
|
versions, but said features are uncertain. ease.js will satisfy the classical OO
|
|
|
|
itch until the time where ECMAScript itself includes it, at which time ease.js
|
|
|
|
will still be useful for providing a transition in order to support older
|
|
|
|
browsers. ease.js may also be useful in the future to augment the feature set of
|
|
|
|
whatever native ECMAScript implementation is decided upon.
|
|
|
|
|
|
|
|
### Why Classical OOP in JavaScript?
|
|
|
|
ease.js was created (historically) for a number of reasons:
|
|
|
|
|
|
|
|
* To "ease" Object-Oriented developers into JavaScript by providing a familiar
|
|
|
|
environment.
|
|
|
|
* To provide the maintenance and development benefits of classical OOP.
|
|
|
|
* To provide features missing from the language, such as proper encapsulation
|
|
|
|
through private/protected members, interfaces, traits, intuitive inheritance,
|
|
|
|
etc.
|
|
|
|
* To encapsulate the hacks commonly used to perform the above tasks.
|
|
|
|
|
|
|
|
Many JS purists believe that classical Object-Oriented programming should be
|
|
|
|
left out of the language and one should stick strictly to prototypal
|
|
|
|
development. While the two are related (both Object-Oriented), they can be
|
|
|
|
applied to different problem domains in order to achieve results that are more
|
|
|
|
natural or intuitive to developers. ease.js works seamlessly with existing
|
|
|
|
prototypes, allowing the developer to choose whether or not they want to use
|
|
|
|
"classes".
|
2010-11-15 12:11:11 -05:00
|
|
|
|
|
|
|
|
|
|
|
## How to Use
|
|
|
|
Please note that, as the project is under active development, the API may change
|
|
|
|
until the first release.
|
|
|
|
|
2011-03-03 20:09:01 -05:00
|
|
|
ease.js uses the [CommonJS](http://commonjs.org) module format. In the
|
2010-11-15 12:11:11 -05:00
|
|
|
examples below, [Node.js](http://nodejs.org) is used.
|
|
|
|
|
2011-04-04 07:42:14 -04:00
|
|
|
### Defining Classes
|
2011-03-07 23:21:15 -05:00
|
|
|
The constructor is provided as the `__construct()` method (influenced by
|
2010-11-15 12:11:11 -05:00
|
|
|
[PHP](http://php.net)).
|
|
|
|
|
2011-05-23 07:01:58 -04:00
|
|
|
````javascript
|
2010-11-15 12:11:11 -05:00
|
|
|
var Class = require( 'easejs' ).Class;
|
|
|
|
|
2011-04-04 07:42:14 -04:00
|
|
|
// anonymous class definition
|
|
|
|
var Dog = Class(
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
2011-04-04 07:42:14 -04:00
|
|
|
'private _name': '',
|
2010-11-15 12:11:11 -05:00
|
|
|
|
2011-04-04 07:42:14 -04:00
|
|
|
'public __construct': function( name )
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
2011-04-04 07:42:14 -04:00
|
|
|
this._name = name;
|
2010-11-15 12:11:11 -05:00
|
|
|
},
|
|
|
|
|
2011-04-04 07:42:14 -04:00
|
|
|
'public bark': function()
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
2011-04-04 07:42:14 -04:00
|
|
|
console.log( 'Woof!' );
|
2010-11-15 12:11:11 -05:00
|
|
|
},
|
2011-04-04 07:42:14 -04:00
|
|
|
|
|
|
|
'public getName': function()
|
|
|
|
{
|
|
|
|
return this._name;
|
|
|
|
}
|
2010-11-15 12:11:11 -05:00
|
|
|
});
|
2011-05-23 07:01:58 -04:00
|
|
|
````
|
2010-11-15 12:11:11 -05:00
|
|
|
|
2011-04-04 07:42:14 -04:00
|
|
|
The above creates an anonymous class and stores it in the variable ``Dog``. You
|
2011-03-05 22:55:15 -05:00
|
|
|
have the option of naming class in order to provide more useful error messages
|
|
|
|
and toString() output:
|
|
|
|
|
2011-05-23 07:01:58 -04:00
|
|
|
````javascript
|
2011-04-04 07:42:14 -04:00
|
|
|
var Dog = Class( 'Dog',
|
2011-03-05 22:55:15 -05:00
|
|
|
{
|
|
|
|
// ...
|
|
|
|
});
|
2011-05-23 07:01:58 -04:00
|
|
|
````
|
2011-03-05 22:55:15 -05:00
|
|
|
|
2010-11-15 12:11:11 -05:00
|
|
|
### 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
|
2011-06-10 14:23:32 -04:00
|
|
|
*not* be added in the future due to problems which have been addressed by
|
2010-11-15 12:11:11 -05:00
|
|
|
interfaces and traits.
|
|
|
|
|
2011-06-10 14:23:32 -04:00
|
|
|
**Note that traits and mixins are not yet available. They are
|
|
|
|
planned features and will be available in the future.**
|
2010-11-15 12:11:11 -05:00
|
|
|
|
2011-05-23 07:01:58 -04:00
|
|
|
````javascript
|
2010-11-15 12:11:11 -05:00
|
|
|
var SubFoo = Foo.extend(
|
|
|
|
{
|
2011-03-07 23:13:06 -05:00
|
|
|
'public anotherMethod': function()
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
{
|
2011-03-07 23:13:06 -05:00
|
|
|
'public anotherMethod': function()
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
|
|
|
},
|
|
|
|
});
|
2011-05-23 07:01:58 -04:00
|
|
|
````
|
2010-11-15 12:11:11 -05:00
|
|
|
|
|
|
|
### Abstract Classes
|
|
|
|
Abstract classes require that their subtypes implement certain methods. They
|
2011-05-23 07:08:35 -04:00
|
|
|
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.
|
2010-11-15 12:11:11 -05:00
|
|
|
|
2011-05-23 07:01:58 -04:00
|
|
|
````javascript
|
2011-05-23 07:12:46 -04:00
|
|
|
var AbstractClass = require( 'easejs' ).AbstractClass;
|
2010-11-15 12:11:11 -05:00
|
|
|
|
2011-05-23 07:08:35 -04:00
|
|
|
var AbstractFoo = AbstractClass(
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
|
|
|
// a function may be provided if you wish the subtypes to implement a
|
|
|
|
// certain number of arguments
|
2011-03-07 23:13:06 -05:00
|
|
|
'abstract public fooBar': [ 'arg' ],
|
2010-11-15 12:11:11 -05:00
|
|
|
|
|
|
|
// alternatively, you needn't supply implementation details
|
2011-03-07 23:13:06 -05:00
|
|
|
'abstract public fooBar2': [],
|
2010-11-15 12:11:11 -05:00
|
|
|
});
|
2011-05-23 07:01:58 -04:00
|
|
|
````
|
2010-11-15 12:11:11 -05:00
|
|
|
|
|
|
|
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
|
2011-05-23 07:08:35 -04:00
|
|
|
be considered abstract and must be declared as such.
|
2010-11-15 12:11:11 -05:00
|
|
|
|
2011-05-23 07:01:58 -04:00
|
|
|
````javascript
|
2010-11-15 12:11:11 -05:00
|
|
|
// can be instantiated because concrete methods are supplied for both
|
|
|
|
// abstract methods
|
2011-05-23 07:08:35 -04:00
|
|
|
var ConcreteFoo = Class.extend( AbstractFoo,
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
2011-03-07 23:13:06 -05:00
|
|
|
'public fooBar': function( arg )
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
|
|
|
},
|
|
|
|
|
2011-03-07 23:13:06 -05:00
|
|
|
'public fooBar2': function()
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
// cannot be instantiated because one abstract method remains
|
2011-05-23 07:08:35 -04:00
|
|
|
var StillAbstractFoo = AbstractClass.extend( AbstractFoo,
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
2011-03-07 23:13:06 -05:00
|
|
|
'public fooBar': function( arg )
|
2010-11-15 12:11:11 -05:00
|
|
|
{
|
|
|
|
},
|
|
|
|
});
|
2011-05-23 07:01:58 -04:00
|
|
|
````
|
2010-11-15 12:11:11 -05:00
|
|
|
|
2011-03-03 19:47:48 -05:00
|
|
|
### Interfaces
|
|
|
|
Interfaces can be declared in a very similar manner to classes. All members of
|
|
|
|
an interface must be declared as abstract.
|
|
|
|
|
2011-05-23 07:01:58 -04:00
|
|
|
````javascript
|
2011-03-03 19:47:48 -05:00
|
|
|
var MyType = Interface(
|
|
|
|
{
|
2011-03-07 23:13:06 -05:00
|
|
|
'abstract public foo': []
|
2011-03-03 19:47:48 -05:00
|
|
|
});
|
2011-05-23 07:01:58 -04:00
|
|
|
````
|
2011-03-03 19:47:48 -05:00
|
|
|
|
|
|
|
To implement an interface, use the `implement()` class method:
|
|
|
|
|
2011-05-23 07:01:58 -04:00
|
|
|
````javascript
|
2011-03-03 19:47:48 -05:00
|
|
|
var ConcreteType = Class.implement( MyType ).extend(
|
|
|
|
{
|
2011-03-07 23:13:06 -05:00
|
|
|
'public foo': function() {}
|
2011-03-03 19:47:48 -05:00
|
|
|
});
|
2011-05-23 07:01:58 -04:00
|
|
|
````
|
2011-03-03 19:47:48 -05:00
|
|
|
|
2011-05-23 07:08:35 -04:00
|
|
|
Note that, if a concrete implementation for each method is not provided, the
|
|
|
|
implementing type must be declared abstract.
|
|
|
|
|
2011-03-03 19:47:48 -05:00
|
|
|
|
2010-11-15 12:11:11 -05:00
|
|
|
## 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:
|
|
|
|
|
2011-01-11 18:30:32 -05:00
|
|
|
* `Class` is used with a capital 'C'
|
|
|
|
* `Interface` is used with a capital 'I'
|
2010-12-28 17:44:33 -05:00
|
|
|
* Reserved keywords are quoted when used (e.g. in property strings)
|
2010-11-15 12:11:11 -05:00
|
|
|
|