Catalog npm
PACKAGE EXPLORERView in registry

34rth-javascript-core-oo

npm

An node/browser library to support full inheritance, mixins, private, public and static variables, event driven programming (publishing/subscribing to instance events) and a global caching mechanism.

cacheclassclassicalconstructorevent drivenextendextendsextensioninheritancemixinmixinsobjectobject orientationoopprototypalprototype
All keywords (19)
staticsuperorientation
Versions collected22
Direct dependencies0From release 1.4.18
Last observed20 Oct, 19:26 UTC

README

Current package documentation

Build Status npm npm

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

<script type="text/javascript" src="oo.js"></script>

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 = require('34rth-javascript-core-oo');

var my_class = earth.core.object.extend(function(_super){
  this.__id__ = 'my_class'; //this is optional for debugging purpose; definition does not have to be included
  
  this.statics = {};//define the statics object:
  this.statics.my_static_function = function(){
    console.log('Hooray, I\'m static');
  };

  this.statics.my_other_static_function = function(){
    console.log('So what, so am I...');
  };

  this.statics.STATIC_VALUE = 'I am like a rock...';

  this.member_variable = 'I am a variable and can be accessed from any instance';

  var private_variable = 'I am shy';

  //I am the constructor, all your base are belong to us
  this.__init = function(a, b, c){
    console.log('Constructing is as easy as ' + a + ' ' + b + ' ' + c);
  };

  this.public_function = function(){
    console.log('total extrovert');
  };

  var private_function = function(){
    console.log('not really introvert, but do not really fancy being seen everywhere, anytime...');
  };
});

//testing the statics
my_class.my_static_function();
my_class.my_other_static_function();
console.log(my_class.STATIC_VALUE);

var my_instance = new my_class(1,2,3);
my_instance.public_function();
try{
  my_instance.private_function();
}catch(e){
  console.log('really, really, really don\'t want to be called');
}
console.log(my_instance.member_variable);
console.log(my_instance.private_variable);//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 = require('34rth-javascript-core-oo');

//definition of bicycle class - extending from the core class
var bicycle = earth.core.object.extend(function(_super){
  this.__id__ = 'bicycle';//this is optional for debugging purposes and can be any random string

  // the bicycle class has three public member variables
  this.cadence = null;
  this.gear = null;
  this.speed = null;

  //constructor function
  this.__init = function(start_cadence, start_speed, start_gear){
    this.gear = start_gear;
    this.speed = start_speed;
    this.cadence = start_cadence;
  };

  this.set_cadence = function(value){
    this.cadence = value;
  };

  this.set_gear = function(value){
    this.gear = value;
  };

  this.apply_brake = function(decrement){
    this.speed -= decrement;
  };
 
  this.speed_up = function(increment){
    this.speed += increment;
  };

  this.get_speed = function(){
    return this.speed; 
  };
});

//definition of mountain_bike class, inheriting from the bicycle class
var mountain_bike = bicycle.extend(function(_super){
  this.__id__ = 'bicycle.mountain_bike';//this is optional for debugging purposes and can be any random string

  //the mountain_bike class adds one more public member variable
  this.seat_height = null;

  //constructor function
  this.__init = function(start_height, start_cadence, start_speed, start_gear){
    _super.__init.call(this, start_cadence, start_speed, start_gear);//call super prototype
    this.seat_height = start_height;
  };

  this.set_height = function(value){
    this.seat_height = value;
  };

	//we're shadowing the function speed_up of bicycle
	this.speed_up = function(increment){
		//on a mountainbike we're speeding up much faster
		this.speed += increment*1.2;
	};

  //we're shadowing the function get_speed of bicycle
  this.get_speed = function(){
    //but we're calling the function of the parent 
    return _super.get_speed.call(this);
  };
});

var bicycle_instance = new bicycle(1, 10, 1);
var mountain_bike_instance = new mountain_bike(90, 1, 10, 1);

console.log(bicycle_instance.speed);//prints 10 as speed of has not been modified
bicycle_instance.speed_up(15);//speeding up by 15 (e.g. m/h)
console.log(bicycle_instance.speed);//prints 25 as speed of has not been modified
console.log(typeof bicycle_instance);//returns object
console.log(bicycle_instance instanceof earth.core.object);//prints true
console.log(bicycle_instance instanceof bicycle);//prints true
console.log(bicycle_instance instanceof mountain_bike);//prints false
try{
	bicycle_instance.set_height(5);
}catch(e){
  console.log('Bicycle does not have a set_height function');
}


console.log(mountain_bike_instance.speed);//prints 10 as speed of has not been modified
mountain_bike_instance.speed_up(5);//speeding up by 5 (e.g. m/h)
console.log(mountain_bike_instance.speed);//prints 16 (10+5*1.2);
console.log(mountain_bike_instance.get_speed() == mountain_bike_instance.speed);//returns true as shadowed function get_speed calls parent function get_speed, returning the current speed
console.log(typeof bicycle_instance);//returns object
console.log(mountain_bike_instance instanceof earth.core.object);//prints true
console.log(mountain_bike_instance instanceof bicycle);//prints true
console.log(mountain_bike_instance instanceof mountain_bike);//prints true 

Static functions

Defining and calling static functions on classes. See example file.

var earth = require('34rth-javascript-core-oo');

var my_static_class = earth.core.object.extend(function(_super){
  this.statics = [];

  this.statics.say_hello = function(name){
    console.log('Hello ' + name);
  };
});

my_static_class.say_hello('Peter');//prints "Hello Peter"

Static functions and inheritance

Inheriting and calling inherited static functions. See example file.

var earth = require('34rth-javascript-core-oo');

var my_parent_static_class = earth.core.object.extend(function(_super){
  this.statics = [];

  this.statics.say_hello = function(name){
    console.log('Hello ' + name);
  };
});

var my_child_static_class = my_parent_static_class.extend(function(_super){
  this.statics = [];

  this.statics.say_bye = function(name){
    console.log('Bye ' + name);
  };
});

my_child_static_class.say_hello('Marry');//prints "Hello Marry"
my_child_static_class.say_bye('Peter');//prints "Bye Peter"
my_parent_static_class.say_hello('Peter');//print "Hello Peter"
try{
  my_parent_static_class.say_bye('Marry');//is not defined and throws an Exception
}catch(e){
  console.log('I am not defined');
}

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 = earth.core.object.extend(function(_super){
  this.__init = function(number){
    console.log('Yaaay, the constructor was just called');
    this.number = number;
  };
});

my_class.add_init_hook(function(_super){
  console.log('Class has been initialised with number ' + this.number);
});

new 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 = require('34rth-javascript-core-oo');

var my_class = earth.core.object.extend(function(_super){
  this.__init = function(number){
    console.log('Yaaay, the constructor just was called');
    this.number = number;
  };

  this.my_special_function = function(){
    console.log('I am ' + this.number + ' times more special than anyone else!');
  };
});

var my_child_class = my_class.extend(function(_super){
  this.__init = function(number){
    _super.__init.call(this, number);
  };
  
  this.my_special_function = function(){
    console.log('Me toooooooo!');
  };
});

my_child_class.add_init_hook(function(_super){
  console.log('Class has been initialised with number ' + this.number);
  _super.my_special_function.call(this);
  this.my_special_function();
});

new 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 = require('34rth-javascript-core-oo');

var speaker = earth.core.mixin.extend(function(_super){
  this.say_something = function(){
    console.log('something');
  };
});

//mixins can also inherit from other mixins
var hello = earth.core.mixin.extend(function(_super){
  this.say_hello = function(name){
    console.log('Hello ' + name);
  };
});

var bye = earth.core.mixin.extend(function(_super){
  this.say_goodbye = function(name){
    console.log('Bye ' + name);
  };
});

var app = earth.core.object.extend(function(_super){
  this.includes = [speaker, hello, bye];//array of mixins to include
});


var test = new app();

test.say_something();//Prints "Something"
test.say_hello('Marry');//prints "Hello Marry"
test.say_goodbye('Marry');//prints "Bye Marry"

Mixins and Inheritance

Mixins can also inherit functions (including full inheritance logic). See example file.

var earth = require('34rth-javascript-core-oo');

var speaker = earth.core.mixin.extend(function(_super){
  this.say_something = function(){
    console.log('something');
  };
});

//mixins can also inherit from other mixins
var speaker_with_good_memory = speaker.extend(function(_super){
  this.names = [];

  this.say_hello = function(name){
    this.names.push(name);
    console.log('Hello ' + this.names.join(', '));
  };
});

var app = earth.core.object.extend(function(_super){
  this.includes = [speaker, speaker_with_good_memory];//array of mixins to include
});


var test = new app();

test.say_something();//Prints "Something"
test.say_hello('Peter');//prints "Hello Peter"
test.say_hello('Marry');//prints "Hello Peter, Marry"
test.say_hello('Charly');//prints "Hello Peter, Marry, Charly"

Mixin and chaining

Trivially, all calls can be chained if desired, by returning this. See example file.

var earth = require('34rth-javascript-core-oo');

var speaker = earth.core.mixin.extend(function(_super){
  this.say_something = function(){
    console.log('something');
    return this;//returns a reference to the object mixing
  };
});

//mixins can also inherit from other mixins
var speaker_with_good_memory = speaker.extend(function(_super){
  this.names = [];

  this.say_hello = function(name){
    this.names.push(name);
    console.log('Hello ' + this.names.join(', '));
    return this;//returns a reference to the object mixing
  };
});

var app = earth.core.object.extend(function(_super){
  this.includes = [speaker, speaker_with_good_memory];//array of mixins to include
});


var test = new app();

test.say_something().say_hello('Peter').say_hello('Marry').say_hello('Charly');

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 = require('34rth-javascript-core-oo');

//definition of bicycle class - extending from the core class
var bicycle = earth.core.object.extend(function(_super){
  this.__id__ = 'bicycle';//this is optional for debugging purposes and can be any random string

  // the bicycle class has three public member variables
  this.cadence = null;
  this.gear = null;
  this.speed = null;

  //constructor function
  this.__init = function(start_cadence, start_speed, start_gear){
    this.gear = start_gear;
    this.speed = start_speed;
    this.cadence = start_cadence;
  };

  this.set_cadence = function(value){
    this.cadence = value;
  };

  this.set_gear = function(value){
    this.gear = value;
  };

  this.apply_brake = function(decrement){
    this.speed -= decrement;
  };
 
  this.speed_up = function(increment){
    this.speed += increment;
  };

  this.get_speed = function(){
    return this.speed; 
  };
}, {super:true});

//definition of mountain_bike class, inheriting from the bicycle class
var mountain_bike = bicycle.extend(function(_super){
  this.__id__ = 'bicycle.mountain_bike';//this is optional for debugging purposes and can be any random string

  //the mountain_bike class adds one more public member variable
  this.seat_height = null;

  //constructor function
  this.__init = function(start_height, start_cadence, start_speed, start_gear){
    this.super(start_cadence, start_speed, start_gear);//call super prototype; EQUIVALENT TO: _super.__init.call(this, start_cadence, start_speed, start_gear);//call super prototype
    this.seat_height = start_height;
  };

  this.set_height = function(value){
    this.seat_height = value;
  };

	//we're shadowing the function speed_up of bicycle
	this.speed_up = function(increment){
		//on a mountainbike we're speeding up much faster
		this.speed += increment*1.2;
	};

  //we're shadowing the function get_speed of bicycle
  this.get_speed = function(){
    //but we're calling the function of the parent 
    return this.super();//EQUIVALENT TO: return _super.get_speed.call(this);
  };
}, {super:true});

var bicycle_instance = new bicycle(1, 10, 1);
var mountain_bike_instance = new mountain_bike(90, 1, 10, 1);

console.log(bicycle_instance.speed);//prints 10 as speed of has not been modified
bicycle_instance.speed_up(15);//speeding up by 15 (e.g. m/h)
console.log(bicycle_instance.speed);//prints 25 as speed of has not been modified
console.log(typeof bicycle_instance);//returns object
console.log(bicycle_instance instanceof earth.core.object);//prints true
console.log(bicycle_instance instanceof bicycle);//prints true
console.log(bicycle_instance instanceof mountain_bike);//prints false
try{
	bicycle_instance.set_height(5);
}catch(e){
  console.log('Bicycle does not have a set_height function');
}


console.log(mountain_bike_instance.speed);//prints 10 as speed of has not been modified
mountain_bike_instance.speed_up(5);//speeding up by 5 (e.g. m/h)
console.log(mountain_bike_instance.speed);//prints 16 (10+5*1.2);
console.log(mountain_bike_instance.get_speed() == mountain_bike_instance.speed);//returns true as shadowed function get_speed calls parent function get_speed, returning the current speed
console.log(typeof bicycle_instance);//returns object
console.log(mountain_bike_instance instanceof earth.core.object);//prints true
console.log(mountain_bike_instance instanceof bicycle);//prints true
console.log(mountain_bike_instance instanceof mountain_bike);//prints true 

PERFORMANCE COMPARISON

Performance comparison against the following libraries/scripts:

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

#Libraryops/mstotal time (in ms)total sample size
134rth13,3554,15140,000,000
2augment12,6634,37240,000,000
3native10,9054,41740,000,000
4Lava.ClassManager monomorphic9,4384,56440,000,000
5Typescript9,3774,65740,000,000
6jsface10,1404,96540,000,000
7Lava.ClassManager polymorphic8,9585,34840,000,000
8inherits8,6005,73840,000,000
9Fiber7,5816,02840,000,000
10John Resig’s Class3,77913,19440,000,000

Specific performance per example

Instantiation (inheritance depth 1)

#Libraryops/mstotal time (in ms)Sample Size
1augment20,734482.3110,000,000
234rth20,343491.5810,000,000
3native16,965589.4510,000,000
4jsface16,937590.4210,000,000
5inherits13,381747.3410,000,000
6Typescript13,336749.8710,000,000
7Lava.ClassManager polymorphic12,748784.4210,000,000
8Lava.ClassManager monomorphic12,093826.9310,000,000
9Fiber11,161895.9810,000,000
10John Resig's Class6,7441,482.7810,000,000

Instantiation (inheritance depth 2)

#Libraryops/mstotal time (in ms)Sample Size
134rth20,392490.3910,000,000
2augment17,876559.4210,000,000
3native13,636733.3710,000,000
4Lava.ClassManager polymorphic12,426804.7710,000,000
5jsface12,332810.8710,000,000
6Lava.ClassManager monomorphic11,824845.7410,000,000
7inherits11,194893.3110,000,000
8Typescript10,630940.7210,000,000
9Fiber9,2101,085.7810,000,000
10John Resig's Class3,8892,571.4910,000,000

Public Method Invocation (inheritance depth 1)

#Libraryops/mstotal time (in ms)Sample Size
1Typescript7,2151,385.9110,000,000
2native7,0491,418.7410,000,000
3Lava.ClassManager monomorphic6,9591,436.9810,000,000
434rth6,7861,473.6310,000,000
5augment6,3161,583.3510,000,000
6jsface6,0881,642.5610,000,000
7Lava.ClassManager polymorphic5,5301,808.4310,000,000
8Fiber5,3811,858.5210,000,000
9inherits5,3071,884.2710,000,000
10John Resig's Class2,5813,875.0110,000,000

Public Method Invocation (inheritance depth 2)

#Libraryops/mstotal time (in ms)Sample Size
1Lava.ClassManager monomorphic6,8761,454.4010,000,000
2Typescript6,3251,580.9310,000,000
3native5,9681,675.6210,000,000
434rth5,8991,695.1310,000,000
5augment5,7251,746.5910,000,000
6jsface5,2041,921.5810,000,000
7Lava.ClassManager polymorphic5,1261,950.8710,000,000
8Fiber4,5702,188.1110,000,000
9inherits4,5192,213.0810,000,000
10John Resig's Class1,9005,264.3210,000,000

Static Method Invocation

#Libraryops/mstotal time (in ms)Sample Size
134rth14,559686.8810,000,000
2Typescript13,608734.8410,000,000
3jsface12,938772.9210,000,000
4inherits12,279814.3810,000,000
5nativen\an\an\a
6John Resig's Classn\an\an\a
7Fibern\an\an\a
8Lava.ClassManager polymorphicn\an\an\a
9Lava.ClassManager monomorphicn\an\an\a
10augmentn\an\an\a

TESTS

For mocha test results see Travis CI.

node make.js && ./node_modules/mocha/bin/mocha

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 22

Collected releases
VersionPublishedDirect dependenciesOpen version
1.4.18Registry latest23 Jan 20170
1.4.1723 Jan 20170
1.4.1623 Jan 20170
1.4.1518 Jan 20170
1.4.1318 Jan 20170
1.4.1211 Jan 20170
1.4.1111 Jan 20170
1.4.102 Jan 20170
1.4.92 Jan 20170
1.4.82 Jan 20170
1.4.72 Jan 20170
1.4.61 Jan 20170
1.4.51 Jan 20170
1.4.41 Jan 20170
1.4.231 Dec 20160
1.4.131 Dec 20160
1.4.031 Dec 20160
1.3.1630 Dec 20161
1.3.1530 Dec 20161
1.3.1430 Dec 20161

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
34rth/34rth-javascript-core-oo

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:26 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:2a81bc60f7b6011ad9596de93d8b744b3df413bd98a211645a664b9e9ac0c8e9