值得深思的連續賦值--賦值運算符運算順序


最近在看到以前前輩留下的文章,對於連續賦值( var a={n:1}; a.x=a={n:2}) )這個知識點,一開始也搞不清楚,但是最終還是說服了自己,談談自己的心得。以下代碼能回答正確的可以忽略本文。

1 var a={n:1};
2 var b=a;
3 a.x = a = {n: 2};
4 console.log(a.x); //?
5 console.log(b.x);//?

正確答案是:

a.x= undefined;
b.x= {n: 2};

疑惑:為什么a.x與b.x不相等呢?為什么a.x會等於undefined呢?

如果你答錯了,那么請你往下看。

 


javascript中的引用賦值

很清楚的一點是:js中對象的賦值其實是引用的賦值,只是將b對象的引用指針指向了a對象的引用。

1 var a={n: 1};
2 var b= a;
3 console.log(b.n); // 1
4 a.n=2;
5 console.log(b.n); // 2

上面的代碼對於一個程序員來說應該都沒有理解上的問題。


賦值運算符的右結合

也就是說賦值運算符是從右向左運算的,這個倒不難理解,例如 var a = 1 + 2; 先計算了等號右邊1+2,將右邊的結果3賦值給了a;當然你也許會說這是運算符的優先級;其實這里本文想要表達的是賦值運算是將“=”右邊賦值給左邊。下面這個例子應該會更加幫助你理解。

1 var a, b;
2 a=b=1+2;

其中按照賦值運算符的右結合的特質:

a = b = 1 + 2 等價於 a = (b= 1+2 )

其中 b 等於 1+2的返回值 3 ;

a 等於 b=3 的返回值 3;


賦值運算符運算順序:從左到右

 雖然上面講到賦值運算符是從右向左運算的,但是其運算順序是從左往右的。也就是說本文一開始提出的問題 a.x = a = {n:2} 是從左向右運算的(賦值是從右向左);也就是說程序的計算順序是:

1 a.x
2 a
3 {n:2}

程序執行到 a.x = a = {n:2} 先執行a.x 並等待賦值符號“=”后面的運算返回值;然后執行a並等待賦值符號“=”后面的運算返回值。


答案是這樣來的

如果看到這有點繞進去了,分析一下本文一開始提出來的例子應該會幫助你更好地了解: 

1 var a={n:1};
2 var b=a;
3 a.x = a = {n: 2};

1. 變量a指向了一個對象{n:1};

2. 變量b指向了a的引用(其實就是{n:1});

3. 計算a.x並等待賦值符號“=”后面的運算返回值(此時,a指向的是{n:1});

4. 計算a並等待賦值符號“=”后面的運算返回值,注意這里將a的引用指向了{n:2};

到這里你是否看出了,第3步a.x的a是{n:1};第4步的a已經被改成了{n:2};

因此當console.log(a.x)的時候就肯定是undifined了;而console.log(b.x)為{n:2};

 

如果到這里還不明白,不妨再增加兩個變量 obj1, obj2; 令obj1={n:1}; obj2={n:2}

1 var obj1={n:1};
2 var obj2={n:2};
3 var a=obj1;
4 var b=a;
5 a.x=a=obj2;
6 console.log(a.x); //undefined
7 console.log(b.x); //{n:2}
8 console.log(obj1); //{n:1, x:{n:2}}
9 console.log(obj2); //{n:2}

其實 a.x=a=obj2 等價於 

a=obj2;

obj1.x=obj2;


作者:AlvinWei  文章出處:韋躐晟的博客 http://www.cnblogs.com/alvinwei1024/p/4856623.html

本文版權歸作者和博客園共有,歡迎轉載

轉載請說明原文章出處


最后

寫代碼時要搞清楚變量間的引用關系,一般情況下不要寫這種容易誤導自己和他人的代碼。我想這種情況一般只會出現在面試題里,用來考核對基礎知識的掌握度。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM