// Demonstrating @jashkenas's examples in an even-more-minimalist version of // classes that only allow object-literal syntax for the class body. // Basic usage; unchanged. class Color { constructor: function(hex) { ... }, r: 1, g: 1, b: 1, copy: function(color) { ... }, setRGB: function(r, g, b) { ... }, setHSV: function(h, s, v) { ... } } // Subclassing; unchanged. class Fox extends Animal { ... } // Class properties; unchanged. Fox.CONSTANT = value; // @jashkenas wrote: // class Student objectContainingStudentProperties class Student {} // copy the own-properties from objectContainingStudentProperties into Student.prototype // I plan to advocate a general |expr .= expr| form instead of "monocle-mustache," // which makes this simple: Student.prototype .= objectContainingStudentProperties; // Notice that this makes it clearer that we are *copying* own properties from the // objectContainingStudentProperties object, instead of, say, sharing or proto-extending. // @jashkenas wrote: // class Protester merge(YoungAdult, WorkEthic, Idealism, { // student: true // }) class Protester {} Protester.prototype .= merge(YoungAdult, WorkEthic, Idealism, { student: true }); // class expressions; unchanged animals.push(class Fox {}); var subclass = function(parent) { return class extends parent; }; // @jashkenas wrote: // var generateModelClass = function(columns) { // var definition = {}; // columns.forEach(function(col) { // definition['get' + col] = function() { // return this[col]; // }; // definition['set' + col] = function(value) { // return this[col] = value; // }; // }); // return class definition; // }; var generateModelClass = function(columns) { var C = class {}; var p = C.prototype; columns.forEach(function(col) { p['get' + col] = function() { return this[col]; }; p['set' + col] = function(value) { return this[col] = value; }; }); return C; }; // Monster class example; unchanged class Monster { constructor: function(name, health) { this.name = name; this.health = health; }, attack: function(target) { log("The monster attacks " + target); }, isAlive: function() { return this.health > 0; }, setHealth: function(value) { if (value < 0) { throw new Error("Health must be non-negative."); } this.health = value; }, numAttacks: 0, attackMessage: "The monster hits you!" } // The point in all this is that you can be just as dynamic if the body // is restricted to an object literal, but you may have to use assignment // to copy own-properties into the prototype from a dynamically computed // source. // tl;dr // Even-more-minimal classes are an expression form ([] means optional): // class [name] [extends parent] [object literal]