Set multiple object values (`a: b: undefined`)

:x: Old way:

let defaltPerson = {
  name: null,
  gender: null,
  age: null,
  country: null,
  username: getId(),
  id: getId()
}

:x: Chained assignments way:

let defaltPerson = {}

defaultPerson.name = defaultPerson.gender = defaultPerson.age = defaultPerson.country = null;
defaultPerson.username = defaultPerson.id = getId();

:x: Hacky function way

let person = {
  ...['name', 'gender', 'age', 'country'].reduce((obj, prop)=>({...obj, [prop]: null}), {}),
  ...['username', 'id'].reduce((obj, prop)=>({...obj, [prop]: getId()}), {}),
}

:x: Hacky function as array prototype way

Array.prototype.ditto = function(v) {
  return this.reduce((o, p)=>({...o, [p]: v}), {})
}

let person = {
  ...['name', 'gender', 'age', 'country'].ditto(null),
  ...['username', 'id'].ditto(getId())
}

:white_check_mark: New way:

let defaltPerson = {
  name: gender: age: country: null,
  username: id: getId()
}

Some methods taken from javascript - Can one set multiple properties inside an object literal to the same value? - Stack Overflow

There's a notable difference between your examples 1,3 versus 2,4,5 in how many times they call getId(). Of course both ways are valid, but in different scenarios ;)

How about extending the pick notation?

const obj = Object.create(null)
obj.{prop1, prop2} = null
// obj.prop1 = obj.prop2 = null

// sadly the second one doesn't exactly match your interest
obj.{prop3, prop4} = getId()
// // obj.prop3 = obj.prop4 = getId()

I guess that behaviour should be implemented through loops;

for(let x of ["prop3", "prop4"])
    obj[x] = getId()

Yes, I know that, getId() may return different values. That is just an implementation detail, so I left it like that.

That would also be doable

sadly the second one doesn't exactly match your interest

Like i said, that's just an implementation detail. Just assume getId returns the same value for now.

I read that and expect the RHS should be an object. To me, obj.{foo, bar} = value looks like sugar for obj.foo = value.foo; obj.bar = value.bar.

source: link

I'd like to propose alternative syntax with another separator:

let object = {
  x|y|z: 1,
  // or
  x/y/z: 1,
}

Such syntax has some advantage over colon based. It can be applied to other kinds of property definitions, not to object initializer only:

class {
  static x/y/z = 1;
  async method/methodAlias() {}
}

Also I find this proposal especially useful with Record & Tuple Proposal, IMO it will simplify usage of complex default values.

@jithujoshyjy - your source link actually explains that syntax in the way @claudiameadows was expecting it to work :p

the syntax obj.{p1, p2} = obj2 means to extract the values of p1 and p2 from obj2 and add them to obj1 .

Yeah, I realised that and wanted to provide some preface ;)

1 Like

What do you think of this notation?

let obj = {
   "hello": "world",
    ["foo", "bar"]: "baz"
}

console.log(obj.foo) // "baz"
console.log(obj.bar) // "baz"

with parens, this already has a meaning:

"hello": "world",
[("foo", "bar")]: "baz"
}

The difference between your example and this one is just one set of parens, and I think that's way too subtle to be a viable option.

Without parens it's also valid syntax.

> obj = { 'world': 2 }
> obj['hello', 'world']
2

Edit: Ignore this post. Don't know what I was thinking. We're talking about object creation, not property access.

TIL - I fully expected it to work in computed property names as well. Seems logical given:

let obj = {
   "hello": "world",
}
obj["foo", "bar"] = "baz"
obj // {hello: 'world', bar: 'baz'}
1 Like

Post still holds - it's the same grammar inside the brackets. (It's part of why brackets were chosen for that syntactic form - it mirrors dynamic property access.)

If you actually execute { ['a', 'b']: 2 }, it throws an error at that comma. Which was very surprising to me - dunno why it disallows a comma there but allows anything else. So unless this is actually a bug in V8 and the comma operator is supposed to work there, like intuition would expect...

It is not a bug. The spec grammar is (roughly):

{
  [AssignmentExpression]: AssignmentExpression
} 

And the comma operator is not an AssignmentExpression, but an Expression.

EDIT: It was already like this in the first edition of the spec from 1997. https://www.ecma-international.org/wp-content/uploads/ECMA-262_1st_edition_june_1997.pdf see section 11.14.

1 Like

But why is it AssignmentExpression and not Expression like bracket access?

1 Like

The issue @senocular is pointing out isn't what AssignmentExpression supports, but the apparent inconsistency between object literal keys (which uses AssignmentExpression) and dynamic property access (which uses Expression). It feels like a spec oversight, so I've filed Shouldn't `ComputedPropertyName` use `Expression` and not `AssignmentExpression`? ยท Issue #2581 ยท tc39/ecma262 ยท GitHub in response. (I'd also prefer to keep further discussion there, to avoid further driving this thread off-topic.)

2 Likes