Generalization of destructuring assignment, has this been discussed before?

Lasse Reichstein reichsteinatwork at
Wed Sep 21 02:35:20 PDT 2011

On Wed, Sep 21, 2011 at 10:27 AM, Brendan Eich <brendan at> wrote:

> On Sep 21, 2011, at 12:17 AM, Lasse Reichstein wrote:
> Destructuring allows, e.g.,
>   var o = {};
>   [o.x, o.y] = [1, 2];
> I.e., a generic LValue as a Field.
> Could this be generalized to working outside of array/object braces in
> declarations, e.g.:
>   var o.x = 42;   // Declared non-configurable
>   const o.x = 37;  // Declared non-Wrtiable and non-configurable
> o must denote an object already, right? Just checking -- some might want o
> if unbound to magically be bound to a fresh object, which would be deeply
> wrong.

Agree, it must be an LValue, which in ES is any expression evaluating to a
Reference (is this how LValue is meant in the destructuring proposal?). If o
isn't declared, then o.x isn't a Reference (just a "ReferenceError" :), and
if it's null or undefined, the Reference is there, but assignment will fail.

> and the *real* reason for suggesting it, a highly convenient shorthand:
>   function { ... }
> This is an oldie, we talked about it in ES1 days, IIRC JScript supported
> (supports?) it.
> I think I have seen this suggested before, but it might just be Crockford's
> web pages at some point (perhaps the one suggesting "::" as abbreviation for
> ".prototype."). Has it been suggested for ES?
> "::" is wanted for guards.
> extends
> CoffeeScript to use :: for guard-ish contracts while leaving Coffee's use of
> :: intact. Yes, significant whitespace.

Not suggesting to use ::, just trying to remember where I saw it :)

There doesn't seem to be any syntactic ambiguity (but it can foil look-ahead
> on functions if function
> calls are allowed as LValues, since "function foo()()()()()()()() { ... } "
> won't know which parenthesis
> starts the arguments until it sees the end of them).
> I don't see how function foo()() is legal unless you are thinking of an
> extension such as ES4/JS1.8+ "expression closures" where the body can be an
> expression.

The problem is that I was suggesting allowing
  function <any LValue>(x) {}
but in ES, a function call can return a Reference, so it would allow
  function foo(x)(x) {}
which is both confusing and will cause the parser to need arbitrary
lookahead in order to know which "(x)" are calls and which is the
declaration. Using "const foo() {} " for declarations is actually even
worse, so I guess there is an ambiguity.

> Ofcourse, "classes" might remove the usecase for "in place function
> declaration" above.
> Sure, but I've never understood why people want to write
> Foo.prototype.m1 = function (...){...};
> Foo.prototype.m2 = function (...){...};
> Foo.prototype.m3 = function (...){...};
> ...
> instead of
> Foo.prototype = {
>   m1: function (...){...},
>   m2: function (...){...},
>   m3: function (...){...},
>   ...
> };

Needless adherence to tradition would require the prototype to have a
.constructor property, so you have to write that too.
I.e., I agree.

> The exact grammar for the dotted expression is unclear. Would you allow any
> member expression, even one with bracketed index expressions? Side effects?
> Where to draw the line?

I would. And that's a good point. If it has side effects, when would those
be evaluated? It seem that declarations on the form "function o.x(){}" would
just be equivalent to "o.x = function x(){}" (except that it's not
configurable). I.e., the saving is minuscule.

> In light of all this, I don't see a strong argument for allowing
> declarations to have dotted expressions instead of identifiers.

I agree. There are too many corner cases, and not enough advantage.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list