Waldemar has put a pretty firm line in the sand regarding the need for a
higher integrity class construct. While I would love to start by agreeing
on max/min as a safety syntax and iterating forward, I appreciate the
desire for such a construct and would probably use it myself. It seems to
me that one of the big reasons for Dart's version of classes is to enforce
this type of integrity. Certainly, it would be useful. The questions is:
how hard would it be to get it to work well this max/min as the base.
Waldemar conceded that he was even fine with const not being the default,
which would have been a much bigger problem. After looking over the const
class section of the harmony class
proposal<http://wiki.ecmascript.org/doku.php?id=harmony:classes#const>and
realized that it could work almost exactly the same. The big thing I
wanted to avoid, though was the public keyword. This is what I came up with
for making a const Monster class from the max/min proposal:
// a private name used by the Monster class
const pHealth = Name.create();
// adding const here triggers a few key things
// 1. The variable Monster will be const
// 2. Monster.prototype is frozen
const class Monster {
// 3. the constructor will be frozen (which includes adding
"static" style functions)
constructor(name, health) {
// 4. anything added to the instance here will be
writable/non-configurable
this.name = name;
// using private names allows protection against mutation from
the outside
this[pHealth] = health;
5. before returning, instance is frozen - see original const
class for details
}
// 6. all other methods on the prototype will also be frozen
attack(target) {
log('The monster attacks ' + target);
}
// get/set (also frozen) can be used to enforce encapsulation on
data members
set health(value) {
if (value < 0) {
throw new Error('Health must be non-negative.')
}
this[pHealth] = value
}
get isAlive() {
return this[pHealth] > 0;
}
}
// cannot reassign
Monster = foo; // error, Monster is const
// cannot modify constructor function
Monster.myStaticFunc = function(){}; // error, constructor is frozen
// cannot modify the prototype
Monster.prototype.bar = bar; // error, prototype is frozen
let m = new Monster("Beholder",45);
m.name = "Fred"
log(m.name); // logs "Fred"
// only has a setter
log(m.health); // error, no getter
m.health = 0;
log(m.isAlive); // logs false
m.randomProp = foo; // error, instance is frozen
The only major difference between what I am proposing now, and the original
const class, is that I stick with just using `this.name = name;` instead of
`public getName(){ return name;}` ( I think `public name = name;` would
have been allowed, and almost exactly what I'm intending instead of adding
a method). Additionally, of course, my proposal is based on max/min instead
of harmony classes, so the other features are obviously not allowed.
The only big hole I'm noticing is that const classes basically could not
have static members. It is future friendly to addition of the static
keyword, though if we wanted to add that.
Here's a max/min const class version of the const class example from
harmony classes:
const pX = Name.create();
const pY = Name.create();
const class Point{
constructor(x,y){
this[pX] = x;
this[pY] = y;
}
get x(){ return this[pX]; }
get y(){ return this[pY]; }
}
I think this could really work, because it is minimal impact, and does not
affect future friendliness. Other additions like private properties and
static methods, for example, would easily fit before ES6 is finalized or as
a future. enhancement.
- Russ
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss