1、 Primer
var a = {n:1}; a.x = a = {n:2}; alert(a.x); // --> undefined
Cai Cai found this writing method when looking at the jQuery source code. The second sentence above a.x = a = {n:2}
Is a continuous assignment expression. What happens to this continuous assignment expression inside the engine? How is it explained?
2、 Conjecture
Conjecture 1: from left to right, a.x is first assigned to {n: 2}, but then a is assigned to {n: 2}, that is, a is rewritten, and the value is {n: 2}. The new a has no x attribute, so it is undefined.
The steps are as follows
a.x = {n:2}; a = {n:2};
The result of this interpretation is consistent with the actual operation result, which seems to be correct.
Note that a.x in conjecture 1 has been assigned.
Guess 2: assign values from right to left, and a is assigned to {n: 2} first. After a.x finds that a is rewritten (before a was {a: 1}), the a.x={n: 2} engine restricts a.x assignment and ignores it.
The steps are as follows:
a = {n:2}; a. X is not assigned {n: 2}
Equivalent to a.x = (a = {n:2})
, that is, the first step has been executed, which can also explain that a.x is undefined.
Note that in conjecture 2, the root of a.x has not been assigned.
3、 Certification
The above two conjectures are believed to be shared by most people. The discussion in the group is stupidly regarded as conjecture 1, and I think it is conjecture 2. In fact, they are all wrong. I ignored the reference relationship.
As follows, add a variable b and point to a.
var a = {n:1}; Var b=a;//Hold a for back check a.x = a = {n:2}; alert(a.x);// --> undefined alert(b.x);// --> [object Object]
It is found that a.x is still undefined, and the magic is that b.x has not been assigned (for example: b.x={n:2})
, turned into [object Object]
。 B is pointing a({n:1})
Only a.x = {n:2}
It indicates that b has the x attribute only after execution. Actual execution process: from right to left, a is first assigned as {n:2}
, then a.x is assigned {n:2}
。
a = {n:2}; a.x = {n:2};
Equivalent to
a.x = (a = {n:2});
The difference from conjecture 2 is that a.x is assigned, and conjecture 2 is not assigned. The most important difference, the first step a = {n:2}
A points to a new object {n:2}
, Step 2 a.x = {n:2}
A in is {a:1}
。
That is, in this continuous statement
a.x = a = {n:2};
a. A in x points to {n:1}
, a points to {n:2}
。
a.x = a = {n:2} │ │ {n:1}<──┘ └─>{n:2}
4: Dispel doubts
Some people may feel dizzy after reading this article. Because the description in the text is really tongue twister.
At first, when I understood this assignment statement
var a = {n:1}; a.x = a = {n:2};
It is believed that the engine will limit the rewriting of a.x (after a is rewritten), but this is not the case. The object pointed to is different. The engine also does not limit the rewriting of a.x={n: 2}.
5: End
Oh, end with another consecutive assignment question. After fun is executed, the variable b here overflows out of fun and becomes a global variable.
Did you think of it?
function fun(){ var a = b = 5; } fun(); alert(typeof a); // --> undefined alert(typeof b); // --> number