Last active
January 16, 2016 09:08
-
-
Save rumkin/40b8d7c963a9ef5a32d8 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// 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