Skip to content

Instantly share code, notes, and snippets.

@dherman
Forked from jashkenas/minimalist-classes.js
Created November 9, 2011 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dherman/1350563 to your computer and use it in GitHub Desktop.
Save dherman/1350563 to your computer and use it in GitHub Desktop.
minimalist classes based on variable-declaration syntax
// Examples using something closer to my original "minimal classes" proposal.
// There are several benefits to this approach.
// First, it uses a familiar approach to separating prototype properties from
// instance properties: methods are on the prototype, and static declarations
// are prototype data properties. Otherwise, instance properties are only
// declared in the constructor body.
// Second, instead of object literal syntax, it uses a property declaration
// closer to variable declarations, which leaves the door open to future
// modifiers such as const or guards.
// Third, it avoids the annoyance of comma separators and allows for semicolon
// insertion.
// First, basic usage from a real-world library (Three.js)
class Color {
constructor(hex) {
...
}
copy(color) {
...
}
setRGB(r, g, b) {
...
}
setHSV(h, s, v) {
...
}
}
// Data properties on the prototype are possible, but this proposal does not
// provide special syntax for them. This avoids making it too easy to make the
// common mistake of putting stateful data on the shared prototype instead of
// creating fresh stateful data on each instance.
Color.prototype .= { r: 1, g: 1, b: 1 }
// To create a class with its prototype chain set correctly:
class Fox extends Animal {
static CONSTANT = value
...
}
// 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.
// The static declaration form adds a class-level property.
// The body is always declarative. But prototypes are their usual, mutable selves,
// so they can easily be added to.
class Student {}
Student.prototype .= objectContainingStudentProperties
// Or even:
class Protester {}
Protester.prototype .= merge(YoungAdult, WorkEthic, Idealism, {
student: true
})
// 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) {
class definition {}
var p = definition.prototype;
columns.forEach(function(col) {
p['get' + col] = function() {
return this[col];
};
p['set' + col] = function(value) {
return this[col] = value;
};
});
return 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(target) {
log("The monster attacks " + target);
}
isAlive() {
return this.health > 0;
}
setHealth(value) {
if (value < 0) {
throw new Error("Health must be non-negative.");
}
this.health = value;
}
}
Monster.prototype.numAttacks = 0
Monster.prototype.attackMessage = "The monster hits you!"
// 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment