On 29/10/11 21:03, Axel Rauschmayer wrote:
There are two things is JavaScript that are simple and elegant and
universally liked:
- Prototypes
- Object literals
How come we can’t transport that simplicity to classes? Once the
objects have been created, we are happy with them, but how to best set
them up is still controversial.
I still maintain that JS doesn't *really* need a declarative syntax for
defining relationships between objects — call it classes if you will.
What I really find lacking in the language are primitives that allow me
to work with objects, by composing them, querying them, filtering them,
whatever-ing them.
I think people already stressed enough the why of having a declarative
syntax for all that (tooling, describing intent, simplicity, etc, etc).
But there's also value in not having another full-blown and different
syntax, imho, as we already have the triangle operator(?), the
monocle-moustache operator(?) and object literals.
Now, for the past few months, I've been defining my objects like this:
// where `clone' = Object.extend(Object.create(proto), props)
var Thing = function(){ return (
{ clone: _clone
, toString: toString
})
function clone(name){ return clone(Thing, { name: name }) }
function toString() { return '[thing ' + this.name + ']' }
}()
var Specific = function(){ return clone(Thing,
{ clone: _clone
, toString: toString
})
function clone(name){ return clone(Specific, { name: name }) }
function toString() { return '[specific ' + this.name + ']' }
}()
var foo = Thing.clone('foo')
var bar = Specific.clone('bar')
/// Using an extended version of object literals
var Thing = {
constructor(name){ this.name = name }
,toString(){ return '[thing ' + this.name + ']' }
}
var Specific = Thing <| {
constructor(name){ this.name = name }
,toString(){ return '[specific ' + this.name + ']' }
}
var foo = new Thing('foo')
var bar = new Specific('foo')
// Clear advantages:
// - Familiar syntax, whilst managing to be quite okay to work with
// - Declarative, but not static
//
// Clear disadvantages:
// - Using `new' in this fashion would require changing semantics for
objects
// - Kinda conflicts with constructor functions. I'd think that factories
// living inside objects and always creating new instances would be
// better, but I know old semantics won't be changed =/
/// Using class syntax
class Thing {
constructor(name){ this.name = name }
toString(){ return '[thing ' + this.name + ']' }
}
class Specific extends Thing {
constructor(name){ this.name = name }
toString(){ return '[specific ' + this.name + ']' }
}
// Clear advantages:
// - Cleaner
// - Can be easily extended to support sugars for traits, privates, and
what-nots
//
// Clear disadvantages:
// - Unfamiliar syntax (for the language itself, not for other languages)
// - Fixed syntax
// - Some could argue the name is quite misleading given the semantics,
but I digress.
Now, I'm not sure class-syntax alone solve the main problems of working
with objects and structuring programs in JavaScript — unless you always
structure your programs using a huge inheritance tree, I favour object
composition, so the class-syntax doesn't change much of what I find
particularly counter-productive in the language. Other people's mileage
may vary.
Anyways, what I feel the language should provide for aiding in the
structure programs is:
- A way of sharing behaviour — semantically covered by prototypes, and
the <| operator is a nice interface for Object.create.
- A way of composing behaviours — traits and mixins. The latter is
already widely used, afaics. Also the .{ operator.
- A set of primitives for working with objects as sets — join,
difference and intersection operations, for example.
With class-syntax you can provide a nice interface to all those, but I
believe the extension proposals to the Object literal already covers
such cases as well, such that you'd get duplicated syntatical sugar for
the same thing.
The major difference I see is that class-syntax, once defined, will be
fixed. They might cover most cases now, but that might not necessarily
hold true as the language and programmers evolve. Providing primitives —
they're mostly independent from class-syntax anyways, which is cool —
allows programmers to evolve the patterns on their own as well.
The one thing class-syntax would excel at, though, is the current
semantics for super calls in ES.next. I find them particularly
confusing, considering the relationship between functions and objects in
JS. They make more sense with a static declarative syntax, but that
might be just me.
None the less, I believe the entry-barrier to both the object literal
syntax and class-syntax to be in the same level, only the class-syntax
looks cleaner and more elegant.
Are we overthinking classes?
Perhaps the reason for all this thinking about classes come from the
role constructor functions take in the language? I'm a bit sceptical on
constructors and constructor's own properties being that important, though.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss