Minimalist (why) classes ?

Quildreen Motta quildreen at gmail.com
Sun Nov 13 02:55:56 PST 2011


On 12/11/11 19:07, John J Barton wrote:
> This kind of discussion illustrates my point: JS is not sweet enough
> because we are missing core operations for constructing prototypes in
> a standard way.
Agreed. I've always thought about JS objects as sets, but it feels weird 
that I don't get disjunction, intersection and other basic operations 
out of the box.

Basically, I've missed primitives for:

- Creating objects that share properties from other objects (Object.create)


- Adding properties to an object (Object.extend)

Object.extend(Object target, Object sources...) → Object
(sources.reduce({|tgt, src|
Object.keys(src).forEach({|key| tgt[key] = src[key]})
tgt }, target)

Should `extend' copy all the properties? Only the "own" properties? I 
feel `own' properties make more sense.


- Defining new objects that extends on the [[Prototype]], which is 
basically Object.create followed by copying the properties of one or 
more objects over to the new instance. (Object.clone? Object.inherit? I 
never felt `extend' quite says it all)

Object.prototype.clone(Object parent, Object mixins...) → Object
(Object.extend.apply(Object.create(parent), mixins))


- Merging (while possibly flattening, as objects can't have several 
[[Prototype]]s) objects.

Object.merge(Object mixins...) → Object
(x = Object.extend.apply({}, mixins))

Dicts are probably a better answer for this one though.


- Creating instances from objects directly (new Stuff, Stuff.new), 
though I'm not sure there's much sense in having two different standard 
ways of doing the same thing. I guess JS is stuck with constructors =/


- Creating objects by removing/renaming certain properties from other 
objects, which is useful for object composition. Though I guess this 
would be handled by traits(?)


Of course, you still need a better syntax to express it all, and the 
proposed extensions to object literals come close to minimalist classes:

var foo = Base.clone({
method1() { },
method2() { },
get stuff() { }
})

var foo = Base <| {
method1() { },
method2() { },
get stuff() { }
}

class foo extends Base {
method1() { }
method2() { }
get stuff() { }
}

That is, if we disregard private and other modifiers. If such modifiers 
were added to the Object literal (meh?), it would be quite the same 
thing. Except a full-blown declarative class syntax could be better 
optimised and would allow for a sugary syntax if/when traits/type guards 
are added.

var foo = Base <| {
#constant: 1, // or const
@private_stuff: bar, // or private
method1() { },
method2() { }
get stuff() { }
}

class foo extends Base {
@private_stuff: bar; // or private
#constant: 1; // or const
method1() { }
method2() { }
get stuff() { }
}

Except I'm not sure the @private could be made to work without creating 
confusing semantics around it, so object literals would still be one 
step behind.


More information about the es-discuss mailing list