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';
function argumentsToArray(args) {
return Array.prototype.slice.call(args);
}
/**
* The original prototype object.
*
* @class __prototype
* @static
*/
var __prototype = {
/**
* This method will be called before returning
* the instance. Put your initialization code here.
*
* @method initialize
*/
initialize: function () {},
};
/**
* Returns an instance of the __prototype 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
* @initialize
*/
var __subject = function subject() {
return Object.create(__prototype);
};
/**
* The prototype object.
* When the __subject function is run, it will
* create an instance of `this.prototype` and call its
* initialize method.
*
* @property prototype
* @type object
*/
__subject.prototype = __prototype;
/**
*
*
* @method inherit
*/
__subject.inherit = function inherit(protoProps) {
_.assign(this.prototype, protoProps);
return this;
};
/**
* Define a function that when run will return an instance
* of its prototype object.
*
* All arguments passed to the extend method
* will be passed on to `this.prototype.extend` method.
*
* @method extend
*/
__subject.extend = function extend(protoProps, staticProps) {
// parent
var parent = this;
// [1] Declare the child variable.
var child;
// [2] Define the child constructor/builder function
// that creates an instance of the prototype object
// and initializes it.
child = function builder() {
var instance = Object.create(child.prototype);
instance.initialize.apply(instance, arguments);
return instance;
};
// [3] Static methods
_.assign(child, parent, staticProps);
// [4] Set the child function's prototype property
// to reference the `nproto`, so that the new prototype may be
// further extended.
child.prototype = Object.create(this.prototype);
child.prototype.constructor = child;
// [5] inherit protoProps.
child.inherit(protoProps);
return child;
};
return __subject;
});
/*
// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var extend = function(protoProps, staticProps) {
var parent = this;
var child;
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent's constructor.
if (protoProps && _.has(protoProps, 'constructor')) {
child = protoProps.constructor;
} else {
child = function(){ return parent.apply(this, arguments); };
}
// Add static properties to the constructor function, if supplied.
_.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate;
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;
return child;
};
*/