-
-
Save rauschma/1336846 to your computer and use it in GitHub Desktop.
| // Roughly: a combination of Jeremy’s and Allen’s ideas, updated with the results of recent discussions | |
| // Guidelines: | |
| // - Don’t use the same syntax as for object literals, but stay close. | |
| // - Rationale: Some object literal features are forbidden in class declarations => don’t confuse people | |
| // - Rationale: Comma separation is a bit tricky. | |
| // - Keep new features at a minimum | |
| // - Don’t obscure the fact that private names are actually name objects. | |
| // => They can also be imported from somewhere else – a use case that needs to be supported. | |
| // - In order to minimize confusion, keep module syntax and class declaration syntax similar. | |
| // Rules: | |
| // - Use @ to refer to name objects | |
| // - there is no syntactic sugar for `this.` | |
| // Name objects: | |
| // - Rough rule for what @foo means: “insert arbitrary identifier here”. | |
| // - Used for property access and to name methods. | |
| // - foo.@bar is syntactic sugar for foo[bar] | |
| // - Rationale: immediately obvious that it’s property access | |
| class Monster extends Being { | |
| // Only methods are allowed here (because these are the prototype’s properties) | |
| // Create name objects that only exist within the declaration’s scope | |
| private age, health, incAge; | |
| // Constructor | |
| // Alternative: use the name "new". Caveat: super.new(name) looks a bit weird. | |
| constructor(name, this.weight, this.@age, this.@health) { | |
| super.constructor(name); | |
| } | |
| getNameObjectForAge() { | |
| return age; | |
| } | |
| // private method | |
| @incAge() { | |
| this.@age++; | |
| } | |
| // getter | |
| get strength() { | |
| // stronger with increasing age... | |
| return super.strength * this.@age; | |
| } | |
| } |
| module name from "@name"; | |
| // Alternatives: use <| operator, use a do-block | |
| let Monster = function () { | |
| let age = name.create(); | |
| let health = name.create(); | |
| let incAge = name.create(); | |
| function Monster(name, weight, age, health) { | |
| super.constructor(name); | |
| this.weight = weight; | |
| this[age] = age; | |
| this[health] = health; | |
| } | |
| Monster.prototype = Object.create(Being.prototype); | |
| Monster.prototype.constructor = Monster; | |
| Monster.prototype.getNameObjectForAge = function () { | |
| return age; | |
| }; | |
| Monster.prototype[incAge] = function () { | |
| this[age]++; | |
| } | |
| Object.defineProperty(Monster.prototype, "strength", { | |
| get: function () { | |
| // stronger with increasing age... | |
| return super.strength * this[age]; | |
| } | |
| }); | |
| return Monster; | |
| }(); |
You forgot the return statement in the desugared section
Is it
Monster.prototype = Object.create(Being);or
Monster.prototype = Object.create(Being.prototype);?
@Raynos: Fixed, thanks.
@domenic: You are absolutely right. Fixed. Error-prone, looking forward to syntactic sugar...
I think you have problem with the desugaring because all methods (but at least the constructor) are non-enumerable, and to match object-initializer, method (not the constructor) should also be non-writable (but configurable), so it would be easier to desugar to one big
Object.create(Being.prototype, {
...
})
Not to mention constructor-inheritance, do you plan it as part of this proposal (then you should use <| when defining Monster function),
@Herby where does it say whether methods should be non-enumerable (only the constructor property should be)
@Herby, @Raynos: I expect the decision on whether or not to make methods non-enumerable (which is done by built-ins, but not by most of the userland code that I have seen) to be final fine-tuning. My first solution was a big Object.create() with property descriptors, but then you have to use [] for the private property names (for which there isn’t consensus, yet).
@Raynos: In draft ES6 spec, it says about object initializers that when short method syntax is used, they are created with enumerable = false, configurable = true and writable = false.
writable false, hmmm, that seems to go against even built-ins. I imagine most would be against it, but IMO it'd be a good thing to force something more explicit (i.e. Object.defineProperty) when overriding existing methods.
@domenic, that's exactly the logic behind those attribute choices for concise methods. If somebody has defined a property as a "method" it should take something more than an assignment to change it.
However, many people find the configurable: true & writable: false combination baffling so it is going to take some effort to keep it in the spec.
Can we have an example of the entire thing desugared?
I attempted to desugar it : https://gist.github.com/2151045