Skip to content

Instantly share code, notes, and snippets.

@yoavniran
Last active May 6, 2024 12:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoavniran/52355ef2431408a0c9d1 to your computer and use it in GitHub Desktop.
Save yoavniran/52355ef2431408a0c9d1 to your computer and use it in GitHub Desktop.
JS Type Extender (inspired by backbone.js)
//IE9+
(function () {
"use strict";
function merge(){ //shallow copy
var root = arguments[0], fromObj;
for (var i = 1; i < arguments.length; i++) {
fromObj = arguments[i];
Object.keys(fromObj).forEach(function(pName){
root[pName] = fromObj[pName];
});
}
return root;
}
return function extenderAttachFn(typeToExtend, inheritExtend) {
typeToExtend.extend = function extend(props) {
var constructor = (props.hasOwnProperty("constructor") ? props.constructor : typeToExtend ); //allow the extending props to define its own constructor method
var newType = function(){
constructor.apply(this, arguments); //only now we call the parent constructor function
};
newType.prototype = merge(Object.create(typeToExtend.prototype), props); //using Object.create we create an object out of the parent prototype without calling the constructor function
if (inheritExtend){ //make the extended type also extendable and so on and so on
extenderAttachFn(newType, true);
}
newType.create = _create.bind(null, constructor, newType.prototype);//allow creating a new instance without the need for New keyword
return newType;
}
};
function _create(constructor, proto){
var instance = Object.create(proto);
var args = Array.prototype.splice.call(arguments, 2);
constructor.apply(instance, args);
return instance;
}
})();
function A(options){
this.name = options.name();
}
A.prototype.doSomething= function(){
console.log("A");
}
extenderAttachFn(A, true);
var B = A.extend({
showName: function(){
console.log("my name = " + this.name);
}
});
B.prototype.doSomething= function(){
console.log("B");
}
var C = A.extend({
showName: function(){
console.log("I am " + this.name);
}
});
C.prototype.doSomething= function(){
console.log("C");
}
var D = B.extend({
showName: function(){
console.log("mi nombre " + this.name);
}
});
D.prototype.doSomething= function(){
console.log("D");
}
var b = new B({name: function(){return "moshe";}});
var b2 = new B({name: function(){return "haim";}});
b.showName();
b.doSomething();
b2.showName();
var c = new C({name: function(){return "James";}});
c.showName();
c.doSomething();
var d = new D({name: function(){return "Angel";}});
var d2 = new D({name: function(){return "Jesus";}});
d.showName();
d.doSomething();
d2.showName();
console.log("b instanceof A = ", b instanceof A);
console.log("b instanceof B = ", b instanceof B);
console.log("c instanceof A = ", c instanceof A);
console.log("c instanceof B = ", c instanceof B);
console.log("d instanceof A = ", d instanceof A);
console.log("d instanceof B = ", d instanceof B);
console.log("d instanceof C = ", d instanceof C);
console.log("d2 instanceof A = ", d2 instanceof A);
console.log("d2 instanceof B = ", d2 instanceof B);
console.log("d2 instanceof C = ", d2 instanceof C);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment