Example usage:
var MyClass = function () { this.count = 0; } .extends(SuperClass) .proto({ myMethod: function() { this.count += MyClass.CONSTANT; // ... }, }) .class({ CONSTANT: 123, });We make use of the fact that ECMAScript 5 allows trailing commas in object literals. The class definition starts with a function expression (a function declaration does not allow you to invoke methods) and then invokes methods on it to extend a superclass, add methods and add class properties.
This is the code that makes the above work:
(function() { function copyOwnTo(source, target) { Object.getOwnPropertyNames(source).forEach(function(propName) { Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName)); }); return target; } Function.prototype.extends = function (superClass) { var thisProto = Object.create(superClass.prototype); // At the very least, we keep the "constructor" property // At most, we preserve additions that have already been made copyOwnTo(this.prototype, thisProto); this.prototype = thisProto; return this; // enable chaining }; Function.prototype.proto = function (protoProps) { copyOwnTo(protoProps, this.prototype); return this; // enable chaining } Function.prototype.class = function (classProps) { copyOwnTo(classProps, this); return this; // enable chaining } }());Note: This pattern is more a proof of concept than something I would use in practice. But I like that this kind of thing can be done in JavaScript.
Related reading: