Skip to content

Instantly share code, notes, and snippets.

@amatiasq
Created August 19, 2013 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amatiasq/6270563 to your computer and use it in GitHub Desktop.
Save amatiasq/6270563 to your computer and use it in GitHub Desktop.
//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;
})();
(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