Last active
December 13, 2015 17:08
-
-
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.
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
// 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