Extending object literal property value shorthand

# Bob Myers (9 years ago)

Thanks Rick. Yes, I had been hoping to make the following work:

x = {a: 1}; y = {b: 2}; z = {x.a, b.y}; // {a: 1, b: 2}

This is not destructuring per se. It's an extension to object literal property value shorthand syntax. The idea was to derive the desired property name a from x.a. This seems compact and readable. However, as you found it could be difficult to define when and how a property name could be derived from various types of member expressions.

Here is an alternative, admittedly not too pretty, but perhaps easier to define and/or implement. The idea is to* generalize the permissible properties in object literals for which values can be omitted/inferred to include LHS destructuring-type syntax*.

If I want to extract the two values from the two objects into variables using destructuring assignment today we can do:

var { x: {a}, y: {b} } = { x, y }; // a=1, b=2

The proposal is to allow the LHS destructuring syntax in the above as a newly allowed shorthand property in an object:

z = { { x: {a}, y: {b} } } // // {a: 1, b: 2}

By using destructuring syntax this way, we would get "renaming" "on-the-fly":

z = { { x: {a: A}, y: {b: B} } } // // {A: 1, B: 2}

Or the ability to pull things from arrays:

q = [1, 2, 3]; z = { { x: {a}, q: [,b]} } // { a: 1, b: 2 }

Or go deeper into an object:

d = { d1: { d2: 3 } }; z = { { x: {a}, d: { d1: {d2} } }; // {a: 1, d2: 3}

The informal definition of how a destructuring-type shorthand property would work is, taking as an example

{ x: {a}, y: {b} }

In a typical destructuring assignment with this on the LHS, x and y refer to the corresponding properties of the object on the RHS, and the properties that are extracted in the end, a and b in this case, are assigned as variables, .

As a destructuring-type shorthand property, however, x and y would refer to the variables x and y in the current scope, and the properties that are extracted in the end, a and b, are set as properties on the resulting object. So it's a kind of "reverse destructuring". Instead of picking out values from properties on an object and assigning those values to variables, we are picking out values from variables and assigning those values to properties on an object.

The notion of allowing destructuring syntax as a property in an object literal could be further expanded by also allowing a value to be provided. If such a value were provided, the top-level properties in the destructuring construct would be interpreted in terms of that value, rather than as variables in the current scope, so that in the simplest case (note the colon)

z = { { x: {a}, y: {b} }: { x, y } } // {a: 1, d2: 3}

The effect is precisely the same as

{ x: {a}, y: {b} } = { x, y }; z = {a, b}

Example with arrays:

z = { [a, b]: [1, 2] } // {a: 1, b: 2}

Of course this conflicts with computed property keys.

I will now go take my meds.

Bob

# Rick Waldron (9 years ago)

Inline...

On Wed, Mar 25, 2015 at 12:25 AM Bob Myers <rtm at gol.com> wrote:

Thanks Rick. Yes, I had been hoping to make the following work:

x = {a: 1}; y = {b: 2}; z = {x.a, b.y}; // {a: 1, b: 2}

This is not destructuring per se.

Of course, and that's not what I was exploring in attempting to extend 12.2.5.9 Runtime Semantics: PropertyDefinitionEvaluation

It's an extension to object literal property value shorthand syntax. The idea was to derive the desired property name a from x.a. This seems compact and readable.

However, as you found it could be difficult to define when and how a property name could be derived from various types of member expressions.

After more thought, I think it can be done with a set of explicit early errors that disallow a subset of MemberExpression nonterminals.