最近看到掘金一篇文章中的有一個題目,比較有意思,所以分享給大家看看。
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
a.x
b.x
複製程式碼
有興趣的可以分析分析,看看答案是多少?五分鐘過去了,答案有了嗎?下面是答案,不知道有沒有跪在這道題上。
a.x // --> undefined
b.x // --> {n: 2}
複製程式碼
思路:
原文中的解題思路是這樣的:
- 優先順序。. 的優先順序高於=,所以先執行a.x,堆記憶體中的{n: 1}就會變成{n: 1, x: undefined},改變之後相應的b.x也變化了,因為指向的是同一個物件。
- 賦值操作是從右到左,所以先執行a = {n: 2},a 的引用就被改變了,然後這個返回值又賦值給了a.x ,需要注意的是這時候a.x 是第一步中的{n: 1, x: undefined}那個物件,其實就是b.x,相當於b.x = {n: 2}
思路很清晰,但是對於第一點,我加入了自己的理解進去。
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
// 這裡引擎會有RHS查詢和LHS查詢
// 具體參見《你不知道的javascript上》
複製程式碼
RHS和LHS:說簡單的就是,在賦值的左右側進行查詢變找,RHS 查詢與簡單地查詢某個變數的值別無二致,而 LHS 查詢則是試圖 找到變數的容器本身,從而可以對其賦值。
直接對a.x = a = {n: 2}分析,這裡在賦值前會有兩個LHS查詢,查詢a.x和a的容器本身,a.x沒有查詢到則宣告瞭一個undefined。
從記憶體模型上分析:
在執行 a.x = a = {n: 2}前:
a.x 和 a 進行LHS時: