Created
August 19, 2013 15:42
-
-
Save amatiasq/6270563 to your computer and use it in GitHub Desktop.
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
//jshint camelcase:false | |
(function() { | |
function noop() {} | |
/** | |
* Returns true if {target} is a function | |
* | |
* @param target The object to analyze | |
* @returns {Boolean} true if target is a function, false otherwise | |
*/ | |
function isFunction(target) { | |
return typeof target === 'function'; | |
} | |
/** | |
* Returns a hashmap with a descriptor for each property on {target} | |
* | |
* @param target {Object} The object to analyze | |
* @returns {Object} a hashmap with the properties descriptors | |
*/ | |
function getDescriptors(target) { | |
var descriptors = {}; | |
Object.getOwnPropertyNames(target).map(function(prop) { | |
descriptors[prop] = Object.getOwnPropertyDescriptor(target, prop); | |
}); | |
return descriptors; | |
} | |
/** | |
* Add every property on {props} into {target} | |
* | |
* @param target {Object} The object where the properties will be added to | |
* @param props {Object} The properties than will be added to {target} | |
* @returns {Object} The first argument | |
* | |
* @example | |
* inject(MyClass.prototype, { | |
* a: 1, | |
* get b() { | |
* return this.a + 1; | |
* } | |
* }); | |
*/ | |
function inject(target, props) { | |
Object.defineProperties(target, getDescriptors(props)); | |
return target; | |
} | |
/** | |
* Prototypes {proto} and adds every property into {props} into the new object | |
* | |
* @param proto {Object} The object than will be used as prototype for the | |
* new object | |
* @param props {Object} The properties than will be added to the new object | |
* @returns {Object} The new object with all properties added | |
* | |
* @example | |
* SubClass.prototype = extend(MyClass.prototype, { | |
* a: 1, | |
* get b() { | |
* return this.a + 1; | |
* } | |
* }); | |
*/ | |
function extend(proto, props) { | |
return Object.create(proto, getDescriptors(props)); | |
} | |
var defaultCtor = { | |
extend: function(config) { | |
ctor(config, this); | |
}, | |
create: function() { | |
var instance = Object.create(this.proto); | |
instance.init.apply(instance, arguments); | |
return instance; | |
}, | |
dispose: function(instance) { | |
instance.dispose(); | |
}, | |
is: function(instance) { | |
return this.proto.isPrototypeOf(instance); | |
} | |
}; | |
/** | |
* Creates a constructor object | |
* | |
* @param Parent {Function|Ctor} The parent constructor function or object | |
* @param config The properties to add to the object created with this constructor | |
* @param statics Overwrites for default constructor methods | |
* @returns {Ctor} A object with methos to create new type of objects | |
*/ | |
function ctor(Parent, config, statics) { | |
if (isFunction(Parent)) | |
Parent = { proto: Parent.prototype }; | |
var proto = Parent ? extend(Parent.proto, config) : config; | |
if (!isFunction(proto.init)) | |
proto.init = noop; | |
if (!isFunction(proto.dispose)) | |
proto.dispose = noop; | |
var Ctor = proto.ctor = extend(defaultCtor, Parent || {}); | |
if (statics) | |
inject(Ctor, statics); | |
Ctor.proto = proto; | |
return Ctor; | |
} | |
window.ctor = ctor; | |
})(); |
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
(function() { | |
function noop() {} | |
function isFunction(obj) { | |
return typeof obj === 'function'; | |
} | |
function extend(proto, props) { | |
var descriptors = {}; | |
Object.getOwnPropertyNames(props).map(function(prop) { | |
descriptors[prop] = Object.getOwnPropertyDescriptor(props, prop) | |
}); | |
return Object.create(proto, descriptors); | |
} | |
function ctor(config, prototype) { | |
function Constructor() { } | |
var proto = Constructor.prototype = prototype ? extend(prototype, config) : config; | |
if (!isFunction(proto.init)) | |
proto.init = noop; | |
if (!isFunction(proto.dispose)) | |
proto.dispose = noop; | |
return proto.ctor = { | |
proto: proto, | |
extend: function(config) { | |
ctor(config, this.proto); | |
}, | |
create: function() { | |
var instance = new Constructor(); | |
instance.init.apply(instance, arguments); | |
return instance; | |
}, | |
dispose: function(instance) { | |
if (!instance.__disposed__) | |
instance.dispose(); | |
}, | |
is: function() { | |
return instance instanceof Construtor; | |
} | |
}; | |
} | |
var Base = ctor({ | |
init: function() { | |
Object.defineProperty(this, { | |
__disposed__: { | |
value: false | |
} | |
}); | |
} | |
dispose: function() { | |
this.__disposed__ = true; | |
this.ctor.dispose(this); | |
} | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment