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

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

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);//?

正確答案是:html

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

疑惑:爲何a.x與b.x不相等呢?爲何a.x會等於undefined呢?java

若是你答錯了,那麼請你往下看。程序員

 


javascript中的引用賦值面試

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

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

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


賦值運算符的右結合code

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

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

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

轉載請說明原文章出處


最後

寫代碼時要搞清楚變量間的引用關係,通常狀況下不要寫這種容易誤導本身和他人的代碼。我想這種狀況通常只會出如今面試題裏,用來考覈對基礎知識的掌握度。

相關文章
相關標籤/搜索