Continuous assignment operation that Javascript may not fully understand after 10 years of writing

original
2012/07/12 12:51
Number of readings 329

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
Expand to read the full text
Loading
Click to lead the topic 📣 Post and join the discussion 🔥
Reward
zero comment
two Collection
three fabulous
 Back to top
Top