1. Introduction
var a = {n:1};
a.x = a = {n:2};
alert(a.x); // --> undefined
This is Cai Cai looking at jQuery I found this way of writing when I found the source code. The second sentence above a.x = a = {n:2} is a continuous assignment expression. What exactly happens inside the engine with this continuous assignment expression? How is it explained?
2. Conjecture Conjecture 1: Assign values from left to right, a.x is assigned {n:2} first, but then a is assigned {n:2} , that is, a has been rewritten, the value is {n:2}, the new a has no x attribute, so it is undefined. The steps are as follows
1, a.x = {n:2};
2, a = {n:2};
The results obtained from this explanation are consistent with the actual operation results, and it seems to be correct. Note that a.x has been assigned in Conjecture 1.
Conjecture 2: Assign values from right to left, a is first assigned to {n:2}, a.x finds that a has been rewritten (previously a was {a:1}), a.x = {n:2} engine limit a.x Assignment, ignored. The steps are as follows:
1, a = {n:2};
2, a.x has not been assigned {n:2}
is equivalent to a.x = (a = {n:2}), that is, executed The first step is taken, which can also explain that a.x is undefined. Note that in Conjecture 2, a.x has not been assigned at all.
3. Proof
I believe most people have the above two conjectures. After discussion in the group, they thought it was conjecture 1, and I thought it was conjecture 2. In fact, they are all wrong. I ignored the reference relationship. As follows, add a variable b pointing to a.
var a = {n:1};
var b = a; // Temporarily store a
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// -- > [object Object]
It is found that a.x is still undefined. The magical thing is that b.x has not been assigned (for example: b.x={n:2}), but becomes [object Object] . b points to a({n:1}). Only when a.x = {n:2} is executed does it mean that b has the x attribute. Actual execution process: from right to left, a is first assigned {n:2}, and then a.x is assigned {n:2}.
1, a = {n:2};
2, a.x = {n:2};
is equivalent to
a.x = (a = {n:2});
The difference from conjecture 2 is that a.x is assigned a value, but not in conjecture 2. The most important difference is that a in the first step a = {n:2} points to the new object {n:2}, and a in the second step a.x = {n:2} is {a:1}. That is, in this consecutive statement
a.x = a = {n :2};
a in a.x points to {n:1}, and a points to {n:2}. As shown below
Four: Solve the doubts
After writing this article, some people may still feel dizzy after reading it. Because the text description inside is really convoluted. When I first understood this consecutive assignment statement
var a = {n:1};
a.x = a = {n:2};
It is thought that the engine will restrict the rewriting of a.x (after a is rewritten), but this is not actually the case . The object pointed to is different. The engine also does not restrict the rewriting of a.x={n:2}.
Thank you to everyone who participated in the discussion: Cai Cai, Dadai, and Ruru. This question was first raised by Cai Cai. Ru Ru is so involved and serious in every discussion in the Rookie Hui Ya Hui group, even if it is a topic raised by others.
Five: End Hey, it ends with another continuous assignment question. After fun is executed, the variable b here overflows outside fun and becomes a global variable. Have you thought about it?
function fun(){
var a = b = 5;
}
fun();
alert(typeof a); // --> undefined
alert(typeof b); // --> number