-
-
Save dherman/1330478 to your computer and use it in GitHub Desktop.
Revisions
-
Dave Herman revised this gist
Nov 1, 2011 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -43,7 +43,7 @@ Fox.CONSTANT = value; 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; -
Dave Herman revised this gist
Nov 1, 2011 . 2 changed files with 152 additions and 156 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,152 @@ // 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 in favor 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] 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 charactersOriginal file line number Diff line number Diff line change @@ -1,156 +0,0 @@ -
jashkenas revised this gist
Nov 1, 2011 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -109,7 +109,7 @@ var generateModelClass = function(columns) { class Monster { constructor: function(name, health) { this.name = name; this.health = health; }, -
jashkenas revised this gist
Nov 1, 2011 . 1 changed file with 6 additions and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -44,9 +44,14 @@ class Fox extends Animal { ... } // Note that "Animal" here is a class object (constructor function) in its // own right. Fox.prototype is set to an instance of Animal that has been // constructed without calling its constructor function -- this is the // usual two-step setting-up-a-prototype shuffle. // There is no special syntax for setting class-level properties, as they are // relatively rare. Just add them to the class object itself: Fox.CONSTANT = value; -
jashkenas created this gist
Nov 1, 2011 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,151 @@ // Here is a proposal for minimalist JavaScript classes, humbly offered. // There are (at least) two different directions in which classes can be steered. // If we go for a wholly new semantics and implementation, then fancier classical // inheritance can be supported with parallel prototype chains for true inheritance // of properties at both the class and instance level. // If however, we keep current JavaScript prototype semantics, and add a form that // can desugar to ES3, things must necessarily stay simpler. This is the direction // I'm assuming here. // If we want to have static class bodies (no executable code at the top level), // then we would do well to reuse the known and loved JavaScript idiom for // fixed lists of properties -- the object literal. // First, basic usage from a real-world library (Three.js) class Color { constructor: function(hex) { ... }, r: 1, g: 1, b: 1, copy: function(color) { ... }, setRGB: function(r, g, b) { ... }, setHSV: function(h, s, v) { ... } } // To create a class with its prototype chain set correctly: class Fox extends Animal { ... } // There is no special syntax for setting class-level properties, as they are // relatively rare. Just add them to the class object (constructor function): Fox.CONSTANT = value; // Note that the right-hand side of a class definition is just an expression, // an object literal is not required. You can be fully dynamic when creating a // class: class Student objectContainingStudentProperties // Or even: class Protester merge(YoungAdult, WorkEthic, Idealism, { student: true }) // The point I'm trying to make being that the own properties of the right hand // side, however they're derived, become the prototypal properties of the resulting // class. // Similarly, class definitions are themselves expressions, and anonymous classes // are equally possible: animals.push(class Fox {}); var subclass = function(parent) { return class extends parent; }; // Naturally, classes can be built up programmatically in this fashion. 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; }; // Finally, the Monster class from the current nutshell proposal // (http://wiki.ecmascript.org/doku.php?id=harmony:classes#the_proposal_in_a_nutshell) // ... sans unnecessary restrictions: class Monster { constructor: (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!" } // I think that's about the run of it. Note what is left out: public / private / // static / frozen / const properties and their ilk. Personally, I'm of the view // that all of these modifiers are deeply undesirable in a language as dynamic // as JavaScript and won't be much used, if added ... but I also think that // getters and setters should be deprecated and removed. // If public / private / static / frozen / const must be a part of class syntax // in JS.next, then they must be valid prefixes for object literals as well -- // and can easily be used to define classes with those properties under this // proposal. // There are no new semantics here, and these classes can easily be transpiled // into ES3 if needed -- just simpler declaration of constructors with prototypal // properties and correctly configured prototype chains. // tl;dr // Classes are a new expression with the form ([] means optional): // class [name] [extends parent] [expression]