Skip to content

Instantly share code, notes, and snippets.

@rtm
Last active December 13, 2015 17:08
Show Gist options
  • Save rtm/4944886 to your computer and use it in GitHub Desktop.
Save rtm/4944886 to your computer and use it in GitHub Desktop.
Myers-style inheritance for JavaScript ES5. Simple, elegant, functional semi-classic implementation of inheritance.
// Class is a meta-class, whose instances are other classes.
// Therefore, to create a class, instantiate Class with A=Class.new().
// To instantiate a class inheriting from another class, use B=Class.new(A).
// After creating a class, optionally assign a constructor with A.ctor=function(){}.
// Within constructor, this.super(...) access constructor of parent class.
// To specify a template for instances of the class, assign to A.proto.
// To instantiate a class, a=A.new(), or specify arguments to be passed to constructor.
//
// Myers-style inheritance as implemented here attempts to be as lightweight as possible.
// It limits itself to the bare necessities.
// If you want a class to have a constructor, set it yourself using A.ctor=.
// If you really want to you can change it later to affect subsequently instantiated objects.
// Same with the prototype used to create new instances of the class.
// This code assume we are in an EC5-compliant environment. However, there is nothing here that
// prevents an Object.create shim from being used. The use of 'new' as a property name would
// probably have to be changed though.
// var Animal=Class.new();
// Animal.ctor=function(name){this.name=name;};
// var Dog=Class.new(Animal);
// Dog.ctor=function(name){this.super(name);};
// Dog.proto={nlegs: 4, bark:function(){...}};
// var Bird=Class.new(Animal);
// Bird.ctor=function(name,breed){this.super(name);this.breed=breed;};
// Bird.proto={nlegs: 2, sing:function(){...}}
//
// var fido=Dog.new("Fido");
// var tweetie=Bird.new("Tweetie","canary");
//
// console.log(tweetie.nLegs); >= 2
// console.log(fido.nLegs) >= 4
// fido.nlegs=3; //poor guy lost a leg
// Dog.proto.nlegs=10; // fido still has 3 legs, other dogs now have 10
var Class = (function(){
var o={
new:function(){
//instantiate an object from the prototype held by its class
var o=Object.create(this.proto);
if(this.ctor){this.ctor.apply(o,arguments);}
return o;
},
ctor:function(sup){
//constructor for classes instantiated from metaclass
this.proto=Object.create(
(sup&&sup.proto)||null,
{super:{value:function(){sup.ctor.apply(this,arguments);}}}
);
}
};
//Classes instantiated from the metaclass inherit the same methods (new) as the metaclass
o.proto=Object.create(o);
return o;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment