The article title of this sentence was originally in a foreign JavaScript specification to see, at that time did not cause enough attention, until the last time a bug found JS in the operation of the even value of the feature (pit).
Online search found an example of a very good even-equal assignment (source 1, source 2):
var a = {N:1};a.x = a = {N:2}; Output?
The answer is:
Console//undefined answer
I do not know if you are correct, at least I was wrong answer.
Then take this opportunity to take a good look at JS Lian, such as the assignment is going on
Assignment order?
Suppose there is a code: A=B=C; , assignment statements are executed from right to left , so the problem is:
is conjecture 1:b = C; A = C;?
or guess 2:b = C; A = B;?
We all know that if two objects point to an object at the same time, the modification of this object is synchronous, such as:
var a={N:1}; var b=a;a.n=2; Console.log (b); //object {N:2}
Therefore, the order of successive assignments can be tested according to this feature.
According to conjecture 1, change C to a specific object, you can see that the modification of a is not synchronized to B, because two {N:1} objects were created on the first and second rows. Such as:
var b={N:1}; var a={N:1};a.n=0; Console.log (b); //object {N:1}
Then according to conjecture 2, the C is replaced by a specific object, you can see that the changes to a are synchronized to B, because A and B reference an object at the same time, such as:
var b={N:1}; var a=b;a.n=0; Console.log (b); //object {n:0}
Test the true hyphen assignment:
var a,b;a=b={N:1};a.n=0; Console.log (b); //object {n:0}
can be seen in accordance with conjecture 2 , if someone feels that the test is not accurate can be tested again, using ECMA5 setter and getter characteristics to test.
First, the setter and getter are applied to the variable name, not the object that the variable is actually stored in, as follows:
Object.defineproperty (window,"obj", { get:function (console.log ("getter!!!");}); var x=obj;obj; //getter!!! Undefinedx; //undefined
You can see that only obj outputs "getter!!!" and X has no output, which is tested with this feature.
Even equal assignment Test 2:
Object.defineproperty (window,"obj", { get:function (console.log ("getter!!!");}); A=b=obj; //getter!!! Undefined
The getter confirms again that in A=b=c, C was read only once.
So, the real arithmetic rule of even equal assignment is B = C; A = B; that is, the continuous assignment is the result of an expression from right to left that always takes the right side of the equal sign to the left of the equals sign .
Can the continuous assignment be disassembled?
Through the above can see the continuous assignment of the real rules, then return to the beginning of the article, if the following rules will be split consecutive assignment will find the results are different, such as:
var a={n:1};a={n:2, x:object}
So the continuous assignment statement, while conforming to the rules of assigning values from right to left, still cannot take the statement apart and write, as to why
I guess : JS internal in order to ensure that the assignment statement is correct, before an assignment statement execution, all the reference address to be assigned to a copy, and then assign the value.
So I think this piece of code A.x=a={n:2}; The logic is:
1, before the execution, will first the A and a.x in the reference address of a are taken out, this value they all point to {N:1}
2. Create a new object in memory {N:2}
3, execute A={n:2}, change A's reference from pointing to {N:1} to pointing to the new {N:2}
4, execute a.x=a, at this time a has pointed to the new object, and a.x because the original reference before execution, so a.x a still point to the original {N:1} object, so add a property x to the original object, the contents of {N:2} is now a
5, the statement execution ends, the original object from {N:1} to {N:1,x:{n:2}}, and the original object because no one references him, so the GC is recycled, the current a point to the new object {N:2}
6, so there is the beginning of the article running results, and then execute a.x, nature is undefined
The above procedure is illustrated by the serial number:
As you can see, the old a.x and the new a all point to the newly created object {N:2}, so they should be congruent .
Test:
var a = {N:1}; var b = a;a.x = a = {N:2}; True
Because we added the Var b=a and added a reference to the original object, it was not released at the 5th step above, confirming the above conclusion.
Postscript
Through this understanding of the characteristics of continuous assignment, and then look back to the article title, it seems to be called:
Try not to use JS's continuous assignment operation unless you really understand its internal mechanisms and the possible consequences.
Finish
JS's even equal assignment value