Object property names can ONLY be strings or Symbols. We can ignore Symbols here. If you actually want to use objects as a key, then you can use a Map
or a Set
.
[u1]: { [posts]: [ p1, p2 ] },
This ☝️ line adds a property named [Object object]
to the database
object. It sets the value associated with that property to a new object that itself is initialised with a property named [Object object]
whose value is set to be an array containing p1
and p2
.
[u2]: { [posts]: [ p3 ] },
This ☝️ line overwrites the value of the property named [Object object]
with a reference to a new object that has one property named [Object object]
that has a value of an array containing p3
.
When referring to an object property with the bracket syntax [<expression>]
, the expression is first evaluated, and the result is then coerced (because JS is weakly typed) to a string, if need be, to form the property name.
u1
and u2
are objects. Using an object as a property key will, by default, result in a call to the abstract internal operation OrdinaryToPrimitive with the hint 'string'
. This will invoke Object.prototype.toString()
, and this will, by default, result in the string '[Object object]'
.
Note that you can override various aspects of this coercion behavior; for example, by implementing your own Symbol.toStringTag
getter method:
class Association {}
class Document {}
class Post extends Document {}
class User extends Document {}
let [ u1, u2 ] = [new User(), new User()]
let [ p1, p2, p3 ] = [ new Post(), new Post(), new Post() ]
let posts = new Association(User, Post, "posts")
Object.defineProperty(u1, Symbol.toStringTag, {
get() { return 'u1' }
})
let database = {
[u1]: { [posts]: [ p1, p2 ] },
[u2]: { [posts]: [ p3 ] },
}
console.log("HERE", JSON.stringify(database))
More details here.