Last active
October 14, 2015 01:08
-
-
Save Skateside/4284435 to your computer and use it in GitHub Desktop.
Just a simpler version of SK80.create from the mixin micro library. Note to self: integrate this
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Extends one object with another. The object in the first argument is | |
* modified. | |
* | |
* @param {Object} source Source object to extend. | |
* @param {Object} extra Additional properties to add to the source object. | |
* @return {Object} Modified source object. | |
*/ | |
function extendObject(source, extra) { | |
var prop = '', | |
owns = Object.prototype.hasOwnProperty; | |
for (prop in extra) { | |
if (owns.call(extra, prop)) { | |
source[prop] = extra[prop]; | |
} | |
} | |
return source; | |
} | |
/** | |
* Creates a new class, possibly based on an old one. | |
* | |
* @param {Function=} Base Optional base class that the new one will inherit | |
* from. | |
* @param {Object} config Static configuration for the new class. | |
* @param {Object} proto Methods and properties to be added to the new class' | |
* prototype. | |
* @return {Function} New class constructor. | |
*/ | |
function createClass(Base, config, proto) { | |
/** | |
* Base function for the new class. All new classes push everything into an | |
* init method. | |
* | |
* @constructor | |
*/ | |
function F() { | |
this.init.apply(this, arguments); | |
} | |
/** | |
* Empty function so a constructor function isn't called when inheriting. | |
* | |
* @constructor | |
*/ | |
function B() {} | |
// Allow the Base to be optional. | |
if (!proto) { | |
proto = config; | |
config = Base; | |
Base = Object; | |
} | |
// Add static properties for the parent and the config. | |
F.config = config; | |
F.parent = Base.prototype; | |
// Inherit from Base. | |
B.prototype = Base.prototype; | |
F.prototype = new B(); | |
// Add the new properties. | |
extendObject(F.prototype, proto); | |
F.prototype.constructor = F; | |
// Return the constructor. | |
return F; | |
} | |
// Example uses: | |
var Person = createClass({ | |
TXT_FOO: 'foo' | |
}, | |
{ | |
init: function (name) { | |
this.name = name + ' ' + Person.config.TXT_FOO; | |
}, | |
getName: function () { | |
return this.name; | |
} | |
}); | |
var Writer = createClass(Person, {}, { | |
init: function (name, books) { | |
Writer.parent.init.call(this, name); | |
this.books = books; | |
}, | |
getBooks: function () { | |
return this.books; | |
} | |
}); | |
var Celeb = createClass(Writer, {}, { | |
init: function (name, books, fame) { | |
Celeb.parent.init.call(this, name, books); | |
this.fame = fame; | |
}, | |
getFame: function () { | |
return this.fame; | |
} | |
}); | |
var person = new Person('a'); | |
var writer = new Writer('c', 'd'); | |
var celeb = new Celeb('e', 'f', 'g'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var FOO = {}; | |
(function (foo) { | |
'use strict'; | |
var constants = { | |
PROP_PROTO: '$proto' | |
}, | |
hasOwn = Object.prototype.hasOwnProperty, | |
toString = Object.prototype.toString, | |
undef; // = undefined; | |
// Checks to ensure that a given object is a Function. | |
// | |
// Takes: | |
// object (Mixed) The object to check. | |
// Returns: | |
// (Boolean) true if a Function, false otherwise. | |
function isFunction(object) { | |
return toString.call(object) === '[object Function]'; | |
} | |
// Works out whether a given object is the global window object. | |
// Based on jQuery.isWindow http://code.jquery.com/jquery-1.8.3.js | |
// | |
// Takes: | |
// object (Mixed) The object to test. | |
// Returns: | |
// (Boolean) true if the object is window, false otherwise. | |
function isWindow(object) { | |
return object !== null && object !== undef && object === object.window; | |
} | |
// Checks an object to see if it's a plain object, rather than something like a | |
// DOM node or window. | |
// Based on jQuery.isPlainObject http://code.jquery.com/jquery-1.8.3.js | |
// | |
// Takes: | |
// object (Mixed) The object to test. | |
// Returns: | |
// (Boolean) true if the object is a plain object, false | |
// otherwise. | |
function isPlainObject(object) { | |
var isPlain = false, | |
key; | |
if (object && typeof object === 'object' && !Array.isArray(object) && | |
!object.nodeType && !isWindow(object)) { | |
for (key in object) { | |
} | |
isPlain = key === undef || hasOwn.call(object, key); | |
} | |
return isPlain; | |
} | |
// Extends source by going through the properties of extra and adding them to | |
// source. If the property of source and extra are both plain objects, those | |
// objects are also enhanced. | |
// | |
// Takes: | |
// source (Object) The source object that should be enhanced. | |
// extras (Object) Object with properties that should be added to | |
// source. | |
// Returns: | |
// (Object) The extended source. | |
function extend(source, extras) { | |
var prop; | |
for (prop in extras) { | |
if (extras.hasOwnProperty(prop)) { | |
if (isPlainObject(source[prop]) && | |
isPlainObject(extras[prop])) { | |
source[prop] = extend({}, source[prop]); | |
source[prop] = extend(source[prop], extras[prop]); | |
} else { | |
source[prop] = extras[prop]; | |
} | |
} | |
} | |
return source; | |
} | |
// Expose the extend function. | |
foo.extend = extend; | |
// Creates an object based on another. The link is live so changes in the parent | |
// object are reflected in the child. Optionally, an object may be passed in | |
// containing a series of properties to add to the created object and arguments | |
// may be passed in to trigger the created object's "init" method. | |
// | |
// Takes: | |
// base (Object) The base object from which the new one should be | |
// made. | |
// [extras] (Object) Extra properties to add to the new object. | |
// [args] (Array) Arguments to be passed to an "init" method of | |
// the new object. | |
// Returns: | |
// (Object) The newly created object. | |
foo.create = function (base, extras, args) { | |
var created = Object.create(base); | |
if (Array.isArray(extras)) { | |
args = extras; | |
extras = null; | |
} | |
if (isPlainObject(extras)) { | |
extend(created, extras); | |
created[constants.PROP_PROTO] = base; | |
} | |
if (Array.isArray(args) && isFunction(created.init)) { | |
created.init.apply(created, args); | |
} | |
return created; | |
}; | |
}(FOO)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment