I understand that the assignment operator is right associative.
So for example x = y = z = 2 is equivalent to (x = (y = (z = 2)))
Great question. The thing to remember here is that JavaScript uses pointers for everything. It's easy to forget this since it is impossible to access the values representing memory addresses in JavaScript (see this SO question). But realizing this is very important in order to understand many things in JavaScript.
So the statement
var foo = {};
creates an object in memory and assigns a pointer to that object to foo. Now when this statement runs:
foo.x = foo = {a: 1};
the property x is actually getting added to the original object in memory, while foo is getting assigned a pointer to a new object, {a: 1}. For example,
var foo, bar = foo = {};
foo.x = foo = {a: 1};
shows that if foo and bar are pointing to the same object initially, bar (which will still point to that original object) will look like {x: {a: 1}}, while foo is simply {a: 1}.
So why doesn't foo look like {a: 1, x: foo}?
While you are right in that assignments are right associative, you must also realize that the interpreter still reads from left to right. Let's take an in-depth example (with some bits abstracted out):
var foo = {};
Okay, create an object in memory location 47328 (or whatever), assign
footo a pointer that points to 47328.
foo.x = ....
Okay, grab the object that
foocurrently points to at memory location 47328, add a propertyxto it, and get ready to assignxto the memory location of whatever's coming next.
foo = ....
Okay, grab the pointer
fooand get ready to assign it to the memory location of whatever's coming next.
{a: 1};
Okay, create a new object in memory at location 47452. Now go back up the chain: Assign
footo point to memory location 47452. Assign propertyxof the object at memory location 47328 to also point to whatfoonow points to--memory location 47452.
In short, there is no shorthand way to do
var foo = {a: 1};
foo.x = foo;