lib/ClassBuilder.js
function ClassBuilder(InstanceBuilder, Parent, Constructor, props) {
	// Last input argument is an object of properties for a new class
	props = arguments[arguments.length - 1];

	// Second last input argument is a constructor function
	Constructor = arguments[arguments.length - 2];

	// Set default Parent class if it is not provided
	if (arguments.length === 3) {
		Parent = Object;
	}

	// Validate input arguments
	// --------------------------------------------------
	if (arguments.length < 3
		|| typeof InstanceBuilder !== 'function'
		|| Object.prototype.toString.call(Parent) !== '[object Function]'
		|| (Constructor !== null && typeof Constructor !== 'function')
		|| Object.prototype.toString.call(props) !== '[object Object]')
	{
		throw new Error('Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)');
	}
	// --------------------------------------------------


	// Extract class name if defined
	// --------------------------------------------------
	var className = '';
	if (typeof props.__name === 'string' && props.__name) {
		className = props.__name;
	}
	delete props.__name;
	// --------------------------------------------------


	// Prepare an array of what is going to be encapsulated into a new class
	// --------------------------------------------------
	var encapsulations = [];
	// Collect objects properties and methods
	if (props.Encapsulate) {
		if (Object.prototype.toString.call(props.Encapsulate) === '[object Array]') {
			encapsulations = encapsulations.concat(props.Encapsulate);
		} else {
			encapsulations.push(props.Encapsulate);
		}

		// Remove "Encapsulate" property, because it is not need to be encapsulated
		delete props.Encapsulate;
	}
	// Put parent's defaults into an encapsulation stack
	if (Parent.prototype.__defaults) {
		encapsulations.unshift(Parent.prototype.__defaults);
	}
	// Put properties and methods for a new class into the encapsulation stack
	encapsulations.push(props);

	// Validate what is going to be encapsulated
	if (encapsulations.some(function(item) {
			var type = Object.prototype.toString.call(item);
			return type !== '[object Function]' && type !== '[object Object]';
		}))
	{
		throw new Error('Some of the items for encapsulation is incorrect. An item can be: Object, Function, Class');
	}
	// --------------------------------------------------



	// Clone class constructor function to prevent a sharing of instance builder function
	// --------------------------------------------------
	var Class;
	var declaration = className
		? 'var ' + className + '; Class = ' + className + ' = '
		: 'Class = ';
	eval(declaration + InstanceBuilder.toString());
	// --------------------------------------------------


	// Inheritance chain
	// --------------------------------------------------
	// Derive a new class from a Parent class
	Class.prototype = Object.create(Parent.prototype);
	// Revert back the reference to the instance builder function
	Class.prototype.constructor = Class;

	// Store the reference to the constructor function
	if (Constructor) {
		Class.prototype.__constructor = Constructor;
	}
	// Create a storage for default properties
	Class.prototype.__defaults = {};

	// Store a reference to a parent's prototype object for internal usage
	Class.__parent = Parent.prototype;
	// --------------------------------------------------


	// Encapsulate properties and methods
	// --------------------------------------------------
	for (var n = 0, N = encapsulations.length; n < N; n++) {
		ClassBuilder.encapsulate(encapsulations[n], Class);
	}
	// --------------------------------------------------


	return Class;
}
function ClassBuilder(InstanceBuilder, Parent, Constructor, props) {
	// Last input argument is an object of properties for a new class
	props = arguments[arguments.length - 1];

	// Second last input argument is a constructor function
	Constructor = arguments[arguments.length - 2];

	// Set default Parent class if it is not provided
	if (arguments.length === 3) {
		Parent = Object;
	}

	// Validate input arguments
	// --------------------------------------------------
	if (arguments.length < 3
		|| typeof InstanceBuilder !== 'function'
		|| Object.prototype.toString.call(Parent) !== '[object Function]'
		|| (Constructor !== null && typeof Constructor !== 'function')
		|| Object.prototype.toString.call(props) !== '[object Object]')
	{
		throw new Error('Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)');
	}
	// --------------------------------------------------


	// Extract class name if defined
	// --------------------------------------------------
	var className = '';
	if (typeof props.__name === 'string' && props.__name) {
		className = props.__name;
	}
	delete props.__name;
	// --------------------------------------------------


	// Prepare an array of what is going to be encapsulated into a new class
	// --------------------------------------------------
	var encapsulations = [];
	// Collect objects properties and methods
	if (props.Encapsulate) {
		if (Object.prototype.toString.call(props.Encapsulate) === '[object Array]') {
			encapsulations = encapsulations.concat(props.Encapsulate);
		} else {
			encapsulations.push(props.Encapsulate);
		}

		// Remove "Encapsulate" property, because it is not need to be encapsulated
		delete props.Encapsulate;
	}
	// Put parent's defaults into an encapsulation stack
	if (Parent.prototype.__defaults) {
		encapsulations.unshift(Parent.prototype.__defaults);
	}
	// Put properties and methods for a new class into the encapsulation stack
	encapsulations.push(props);

	// Validate what is going to be encapsulated
	if (encapsulations.some(function(item) {
			var type = Object.prototype.toString.call(item);
			return type !== '[object Function]' && type !== '[object Object]';
		}))
	{
		throw new Error('Some of the items for encapsulation is incorrect. An item can be: Object, Function, Class');
	}
	// --------------------------------------------------



	// Clone class constructor function to prevent a sharing of instance builder function
	// --------------------------------------------------
	var Class;
	var declaration = className
		? 'var ' + className + '; Class = ' + className + ' = '
		: 'Class = ';
	eval(declaration + InstanceBuilder.toString());
	// --------------------------------------------------


	// Inheritance chain
	// --------------------------------------------------
	// Derive a new class from a Parent class
	Class.prototype = Object.create(Parent.prototype);
	// Revert back the reference to the instance builder function
	Class.prototype.constructor = Class;

	// Store the reference to the constructor function
	if (Constructor) {
		Class.prototype.__constructor = Constructor;
	}
	// Create a storage for default properties
	Class.prototype.__defaults = {};

	// Store a reference to a parent's prototype object for internal usage
	Class.__parent = Parent.prototype;
	// --------------------------------------------------


	// Encapsulate properties and methods
	// --------------------------------------------------
	for (var n = 0, N = encapsulations.length; n < N; n++) {
		ClassBuilder.encapsulate(encapsulations[n], Class);
	}
	// --------------------------------------------------


	return Class;
}
function ClassBuilder ( InstanceBuilder , Parent , Constructor , props ) { // Last input argument is an object of properties for a new class props = arguments [ arguments . length - 1 ] ; // Second last input argument is a constructor function Constructor = arguments [ arguments . length - 2 ] ; // Set default Parent class if it is not provided if ( arguments . length === 3 ) { Parent = Object ; } // Validate input arguments // -------------------------------------------------- if ( arguments . length < 3 || typeof InstanceBuilder !== 'function' || Object . prototype . toString . call ( Parent ) !== '[object Function]' || ( Constructor !== null && typeof Constructor !== 'function' ) || Object . prototype . toString . call ( props ) !== '[object Object]' ) { throw new Error ( 'Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)' ) ; } // -------------------------------------------------- // Extract class name if defined // -------------------------------------------------- var className = '' ; if ( typeof props . __name === 'string' && props . __name ) { className = props . __name ; } delete props . __name ; // -------------------------------------------------- // Prepare an array of what is going to be encapsulated into a new class // -------------------------------------------------- var encapsulations = [ ] ; // Collect objects properties and methods if ( props . Encapsulate ) { if ( Object . prototype . toString . call ( props . Encapsulate ) === '[object Array]' ) { encapsulations = encapsulations . concat ( props . Encapsulate ) ; } else { encapsulations . push ( props . Encapsulate ) ; } // Remove "Encapsulate" property, because it is not need to be encapsulated delete props . Encapsulate ; } // Put parent's defaults into an encapsulation stack if ( Parent . prototype . __defaults ) { encapsulations . unshift ( Parent . prototype . __defaults ) ; } // Put properties and methods for a new class into the encapsulation stack encapsulations . push ( props ) ; // Validate what is going to be encapsulated if ( encapsulations . some ( function ( item ) { var type = Object . prototype . toString . call ( item ) ; return type !== '[object Function]' && type !== '[object Object]' ; } ) ) { throw new Error ( 'Some of the items for encapsulation is incorrect. An item can be: Object, Function, Class' ) ; } // -------------------------------------------------- // Clone class constructor function to prevent a sharing of instance builder function // -------------------------------------------------- var Class ; var declaration = className ? 'var ' + className + '; Class = ' + className + ' = ' : 'Class = ' ; eval ( declaration + InstanceBuilder . toString ( ) ) ; // -------------------------------------------------- // Inheritance chain // -------------------------------------------------- // Derive a new class from a Parent class Class . prototype = Object . create ( Parent . prototype ) ; // Revert back the reference to the instance builder function Class . prototype . constructor = Class ; // Store the reference to the constructor function if ( Constructor ) { Class . prototype . __constructor = Constructor ; } // Create a storage for default properties Class . prototype . __defaults = { } ; // Store a reference to a parent's prototype object for internal usage Class . __parent = Parent . prototype ; // -------------------------------------------------- // Encapsulate properties and methods // -------------------------------------------------- for ( var n = 0 , N = encapsulations . length ; n < N ; n ++ ) { ClassBuilder . encapsulate ( encapsulations [ n ] , Class ) ; } // -------------------------------------------------- return Class ; }
Main class builder.
It takes the constructor function and wraps it to add few automated processes for constructing a new class.

Properties and features:
- set the parent class
- save the inheritance chain
- define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous objects, even parent class. Only the own properties of the new class will have the highest precedence
- the reference to the parent class is stored in 'parent' property
- inherited methods are stored in class prototype object
- store default class properties in '__default' object where the objects will be copied, not shared

@see {@link Class}
@see {@link SingletonClass}

@throws {Error} Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)
@throws {Error} Some of the items for encapsulation is incorrect. An item can be: Object, Function, Class

@param {Function} InstanceBuilder - Function that defines how instances will be created, how constructor(s) will be executed
@param {Function} [Parent = Object] - Parent class
@param {Function | null} Constructor - Constructor function
@param {Object} props - Object of properties and methods for a new class. Property names that are used internally and will be ignored by encapsulation:
- __constructor
- __parent

If some of the object has "__defaults" object, then all of it's properties will be treated as an object of default properties that a new class should have.
@param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class
@param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.
@returns {Function} Class
Main class builder . It takes the constructor function and wraps it to add few automated processes for constructing a new class .