Skip to content

Instantly share code, notes, and snippets.

@rumkin
Last active January 16, 2016 09:08
Show Gist options
  • Save rumkin/40b8d7c963a9ef5a32d8 to your computer and use it in GitHub Desktop.
Save rumkin/40b8d7c963a9ef5a32d8 to your computer and use it in GitHub Desktop.
// Extend class
function extend (proto) {
var Super = this;
var ctor;
if (proto.hasOwnProperty('constructor')) {
ctor = proto.constructor;
} else {
ctor = function () {
Super.apply(this, arguments);
};
}
Object.setPrototypeOf(ctor.prototype, this.prototype);
// Copy static methods and properties.
Object.getOwnPropertyNames(Super).forEach((name) => {
if (['arguments', 'length', 'name', 'caller', 'prototype'].indexOf(name) > -1) {
return;
}
Object.defineProperty(
ctor,
name,
Object.getOwnPropertyDescriptor(Super, name)
);
});
// Copy prototype methods and properties.
Object.getOwnPropertyNames(proto).forEach((name) => {
if (name === 'constructor') {
return;
}
Object.defineProperty(
ctor.prototype,
name,
Object.getOwnPropertyDescriptor(proto, name)
);
});
return ctor;
}
// Static new
function new_() {
var instance = Object.create(this.prototype);
this.apply(instance, arguments);
return instance;
};
// Basic type
function Type() {}
Type.extend = extend;
Type.new = new_;
// Implement interface (copy methods)
function interface(target, source) {
Array.prototype.concat.apply([], arguments).slice(1).forEach(
function(source) {
if (typeof source !== 'function') {
return;
}
var proto = source.prototype;
Object.getOwnPropertyNames(proto).forEach(function(name){
var value = proto[name];
if (name === 'constructor') {
return;
}
if (typeof value === 'function') {
target.prototype[name] = value;
}
});
}
);
}
// Check if class implements interface (has exactly the same methods).
function implements(target, source) {
var match = true;
Object.getOwnPropertyNames(source.prototype).forEach(function(name){
var value = source.prototype[name];
if (name === 'constructor') {
return;
}
if (typeof value === 'function') {
if (! target.prototype.hasOwnProperty(name) || target.prototype[name] !== value) {
match = false;
}
};
});
return match;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment