API Docs for: 0.0.0
Show:

File: src/subject.js

//     subject
//     (c) simonfan
//     subject is licensed under the MIT terms.

/**
 * Expressive prototypal inheritance.
 *
 * @module subject
 */

/* jshint ignore:start */
if (typeof define !== 'function') { var define = require('amdefine')(module) }
/* jshint ignore:end */

define(['lodash'], function (_) {
	'use strict';

	/**
	 * The original base object.
	 * 
	 * @class __base
	 * @static
	 */
	var __base = {
		/**
		 * This method will be called before returning
		 * the instance. Put your initialization code here.
		 * 
		 * @method initialize
		 */
		initialize: function () {},

		/**
		 * Takes any number of objects as arguments
		 * and extend the values to this one.
		 * Overwrite this property to have new behaviour
		 * on the next extension.
		 * 
		 * @method extend
		 */
		extend: function () {
			var args = Array.prototype.slice.call(arguments);
			args.unshift(this);
			_.extend.apply(_, args);

			return this;
		}
	};

	/**
	 * Returns an instance of the __base object.
	 * 
	 * This function is a simplified equivalent of
	 * the one returned by `__subject.define`.
	 * The only difference is that initialize method is not invoked.
	 * 
	 * @class __subject
	 * @constructor
	 */
	var __subject = function subject() {
		return Object.create(__base);
	};

	/**
	 * The base object.
	 * When the __subject function is run, it will
	 * create an instance of `this.base` and call its
	 * initialize method.
	 * 
	 * @property base
	 * @type object
	 */
	__subject.base = __base;


	/**
	 * Define a function that when run will return an instance
	 * of its base object.
	 * 
	 * All arguments passed to the extend method
	 * will be passed on to `this.base.extend` method.
	 * 
	 * @method extend
	 */
	__subject.extend = function extend() {

		// [1] Create an instance of 'this.base'
		var newbase = Object.create(this.base);

		// [2] Call 'newbase.extend' passing it all the arguments
		//     with which extend was called.
		//     The 'extend' method is extend
		newbase.extend.apply(newbase, arguments);

		// [3] Create a builder function 
		//     that creates an instance of the base object
		//     and initializes it.
		var builder = function builder() {
			var instance = Object.create(newbase);
			instance.initialize.apply(instance, arguments);

			return instance;
		};

		// [4] Set the builder function's base property
		//     to reference the `newbase`, so that the new base may be 
		//     further extended.
		builder.base = newbase;

		// [5] Define an extend
		builder.extend = this.extend;

		// some aliases
		builder.define = builder.extend;

		return builder;
	};

	// aliases
	__subject.define = __subject.extend;

	return __subject;
});