TABLE OF CONTENTS
GENERAL
JavaScript (node.js/browser) library for inheritance and mixins in JavaScript with strong coupling of contexts. Includes private/public/static members/functions as well as mixin architecture (borrowing functionality from mixins);
The package/framework is 100% stand-alone and is not dependant on any other npm packages. The packages listed in node_modules are exclusively for the performance comparison modules required to compare the baseline performances.
INSTALLATION
in Node.js
npm install 34rth-javascript-core-oo
in Browser
Download the /bin/oo.js file from github
EXAMPLES
Classes (private/public variables/functions)
The example below shows the private, public functions/members, static functions and variables as well as the constructor. See example file.
var earth = ; var my_class = earthcoreobject; //testing the staticsmy_class;my_class;console; var my_instance = 123;my_instance;try my_instance;catche console;console;console;//undefined... they said they're shy :)
Simple class inheritance and _super
Code example for simple inheritance calling _super constructor and methods. See example file.
var earth = ; //definition of bicycle class - extending from the core classvar bicycle = earthcoreobject; //definition of mountain_bike class, inheriting from the bicycle classvar mountain_bike = bicycle; var bicycle_instance = 1 10 1;var mountain_bike_instance = 90 1 10 1; console;//prints 10 as speed of has not been modifiedbicycle_instance;//speeding up by 15 (e.g. m/h)console;//prints 25 as speed of has not been modifiedconsole;//returns objectconsole;//prints trueconsole;//prints trueconsole;//prints falsetry bicycle_instance;catche console; console;//prints 10 as speed of has not been modifiedmountain_bike_instance;//speeding up by 5 (e.g. m/h)console;//prints 16 (10+5*1.2);console;//returns true as shadowed function get_speed calls parent function get_speed, returning the current speedconsole;//returns objectconsole;//prints trueconsole;//prints trueconsole;//prints true
Static functions
Defining and calling static functions on classes. See example file.
var earth = ; var my_static_class = earthcoreobject; my_static_class;//prints "Hello Peter"
Static functions and inheritance
Inheriting and calling inherited static functions. See example file.
var earth = ; var my_parent_static_class = earthcoreobject; var my_child_static_class = my_parent_static_class; my_child_static_class;//prints "Hello Marry"my_child_static_class;//prints "Bye Peter"my_parent_static_class;//print "Hello Peter"try my_parent_static_class;//is not defined and throws an Exceptioncatche console;
Init Hooks
Init hooks allow to trigger any number of callback functions whenever a new instance of a class is created. Init hooks traverse the whole prototype chain (ie parent's init hooks will also get triggered). See example file.
var my_class = earthcoreobject; my_class; 10;//'Yaaay, the constructor was just called//Class has been initialised with number 10
Init Hooks and _super
Init hooks also allow access to _super (always in context) so shadowed functions can be called. See example file.
var earth = ; var my_class = earthcoreobject; var my_child_class = my_class; my_child_class; 10;//Yaaay, the constructor just was called//Class has been initialised with number 10//I am 10 times more special than anyone else!//Me toooooooo!
Mixins
Mixins can be used to implement functionality that can be shared between classes. As a class can only inherit from one other class (JAVA-style) mixins allow a way to reduce duplication of code (think aspect oriented programming in JAVA). See example file.
var earth = ; var speaker = earthcoremixin; //mixins can also inherit from other mixinsvar hello = earthcoremixin; var bye = earthcoremixin; var app = earthcoreobject; var test = ; test;//Prints "Something"test;//prints "Hello Marry"test;//prints "Bye Marry"
Mixins and Inheritance
Mixins can also inherit functions (including full inheritance logic). See example file.
var earth = ; var speaker = earthcoremixin; //mixins can also inherit from other mixinsvar speaker_with_good_memory = speaker; var app = earthcoreobject; var test = ; test;//Prints "Something"test;//prints "Hello Peter"test;//prints "Hello Peter, Marry"test;//prints "Hello Peter, Marry, Charly"
Mixin and chaining
Trivially, all calls can be chained if desired, by returning this. See example file.
var earth = ; var speaker = earthcoremixin; //mixins can also inherit from other mixinsvar speaker_with_good_memory = speaker; var app = earthcoreobject; var test = ; test;
Syntactic sugar (super calls in every class)
There is an in-built option to enable syntactic super sugar to have direct reference to super methods throughout the private/public class functions. Please note that the super sugar comes at a performance penalty of roughtly 40% compared to the results in the PERFORMANCE COMPARISON. The example below is the same as in Simple class inheritance and _super just with syntactic super sugar turned on.
Enabling the super sugar is done by passing the option {super:true} to the class definition as per the example file below.
var earth = ; //definition of bicycle class - extending from the core classvar bicycle = earthcoreobject; //definition of mountain_bike class, inheriting from the bicycle classvar mountain_bike = bicycle; var bicycle_instance = 1 10 1;var mountain_bike_instance = 90 1 10 1; console;//prints 10 as speed of has not been modifiedbicycle_instance;//speeding up by 15 (e.g. m/h)console;//prints 25 as speed of has not been modifiedconsole;//returns objectconsole;//prints trueconsole;//prints trueconsole;//prints falsetry bicycle_instance;catche console; console;//prints 10 as speed of has not been modifiedmountain_bike_instance;//speeding up by 5 (e.g. m/h)console;//prints 16 (10+5*1.2);console;//returns true as shadowed function get_speed calls parent function get_speed, returning the current speedconsole;//returns objectconsole;//prints trueconsole;//prints trueconsole;//prints true
PERFORMANCE COMPARISON
Performance comparison against the following libraries/scripts:
- inherit
- Lava Class Manager
- TypeScript
- Fiber
- John Resig's extend function
- Augment
- jsface
- Native JavaScript inheritance
To run the performance tests, run
node performance/run_proprietary.js
There are two parameters available:
- --benchmark/-b: the type of benchmark to run. Valid values: instantiation, public, static
- --class/-c: the class that should be benchmarked.
Overall performance results
# | Library | ops/ms | total time (in ms) | total sample size |
---|---|---|---|---|
1 | 34rth | 13,355 | 4,151 | 40,000,000 |
2 | augment | 12,663 | 4,372 | 40,000,000 |
3 | native | 10,905 | 4,417 | 40,000,000 |
4 | Lava.ClassManager monomorphic | 9,438 | 4,564 | 40,000,000 |
5 | Typescript | 9,377 | 4,657 | 40,000,000 |
6 | jsface | 10,140 | 4,965 | 40,000,000 |
7 | Lava.ClassManager polymorphic | 8,958 | 5,348 | 40,000,000 |
8 | inherits | 8,600 | 5,738 | 40,000,000 |
9 | Fiber | 7,581 | 6,028 | 40,000,000 |
10 | John Resig’s Class | 3,779 | 13,194 | 40,000,000 |
Specific performance per example
Instantiation (inheritance depth 1)
# | Library | ops/ms | total time (in ms) | Sample Size |
---|---|---|---|---|
1 | augment | 20,734 | 482.31 | 10,000,000 |
2 | 34rth | 20,343 | 491.58 | 10,000,000 |
3 | native | 16,965 | 589.45 | 10,000,000 |
4 | jsface | 16,937 | 590.42 | 10,000,000 |
5 | inherits | 13,381 | 747.34 | 10,000,000 |
6 | Typescript | 13,336 | 749.87 | 10,000,000 |
7 | Lava.ClassManager polymorphic | 12,748 | 784.42 | 10,000,000 |
8 | Lava.ClassManager monomorphic | 12,093 | 826.93 | 10,000,000 |
9 | Fiber | 11,161 | 895.98 | 10,000,000 |
10 | John Resig's Class | 6,744 | 1,482.78 | 10,000,000 |
Instantiation (inheritance depth 2)
# | Library | ops/ms | total time (in ms) | Sample Size |
---|---|---|---|---|
1 | 34rth | 20,392 | 490.39 | 10,000,000 |
2 | augment | 17,876 | 559.42 | 10,000,000 |
3 | native | 13,636 | 733.37 | 10,000,000 |
4 | Lava.ClassManager polymorphic | 12,426 | 804.77 | 10,000,000 |
5 | jsface | 12,332 | 810.87 | 10,000,000 |
6 | Lava.ClassManager monomorphic | 11,824 | 845.74 | 10,000,000 |
7 | inherits | 11,194 | 893.31 | 10,000,000 |
8 | Typescript | 10,630 | 940.72 | 10,000,000 |
9 | Fiber | 9,210 | 1,085.78 | 10,000,000 |
10 | John Resig's Class | 3,889 | 2,571.49 | 10,000,000 |
Public Method Invocation (inheritance depth 1)
# | Library | ops/ms | total time (in ms) | Sample Size |
---|---|---|---|---|
1 | Typescript | 7,215 | 1,385.91 | 10,000,000 |
2 | native | 7,049 | 1,418.74 | 10,000,000 |
3 | Lava.ClassManager monomorphic | 6,959 | 1,436.98 | 10,000,000 |
4 | 34rth | 6,786 | 1,473.63 | 10,000,000 |
5 | augment | 6,316 | 1,583.35 | 10,000,000 |
6 | jsface | 6,088 | 1,642.56 | 10,000,000 |
7 | Lava.ClassManager polymorphic | 5,530 | 1,808.43 | 10,000,000 |
8 | Fiber | 5,381 | 1,858.52 | 10,000,000 |
9 | inherits | 5,307 | 1,884.27 | 10,000,000 |
10 | John Resig's Class | 2,581 | 3,875.01 | 10,000,000 |
Public Method Invocation (inheritance depth 2)
# | Library | ops/ms | total time (in ms) | Sample Size |
---|---|---|---|---|
1 | Lava.ClassManager monomorphic | 6,876 | 1,454.40 | 10,000,000 |
2 | Typescript | 6,325 | 1,580.93 | 10,000,000 |
3 | native | 5,968 | 1,675.62 | 10,000,000 |
4 | 34rth | 5,899 | 1,695.13 | 10,000,000 |
5 | augment | 5,725 | 1,746.59 | 10,000,000 |
6 | jsface | 5,204 | 1,921.58 | 10,000,000 |
7 | Lava.ClassManager polymorphic | 5,126 | 1,950.87 | 10,000,000 |
8 | Fiber | 4,570 | 2,188.11 | 10,000,000 |
9 | inherits | 4,519 | 2,213.08 | 10,000,000 |
10 | John Resig's Class | 1,900 | 5,264.32 | 10,000,000 |
Static Method Invocation
# | Library | ops/ms | total time (in ms) | Sample Size |
---|---|---|---|---|
1 | 34rth | 14,559 | 686.88 | 10,000,000 |
2 | Typescript | 13,608 | 734.84 | 10,000,000 |
3 | jsface | 12,938 | 772.92 | 10,000,000 |
4 | inherits | 12,279 | 814.38 | 10,000,000 |
5 | native | n\a | n\a | n\a |
6 | John Resig's Class | n\a | n\a | n\a |
7 | Fiber | n\a | n\a | n\a |
8 | Lava.ClassManager polymorphic | n\a | n\a | n\a |
9 | Lava.ClassManager monomorphic | n\a | n\a | n\a |
10 | augment | n\a | n\a | n\a |
TESTS
For mocha test results see Travis CI.
node make.js && ./node_modules/mocha/bin/mocha