javascript中的賦值我們都知道,是從右到左的
var a = b = c
上面的語句實際執行時是這樣的
b = c
var a = b
但是如果有物件參與進來呢?昨天看到的一個例子
var foo = { a: 2 }
var bar = foo
foo.x = foo = { b: 3 }
前兩行很簡單,就是將bar也指向了foo。
第三行,剛開始是執行foo = { b: 3 },這樣將foo重新指向了另一個物件。
接下來的一句foo.x = foo,這句我本來以為是foo.x指向foo,這樣foo就成了一個循環引用自身的對象,即
foo = {
b: 3,
x: {
b: 3,
x: {
b: 3,
x: {
......
}
}
}
}
但實際測試發現,foo.x = foo這句裡面的foo.x中的foo是指向bar,也就是還沒重新賦值的foo,有點不太理解,感覺應該是解析時候是從左到右右,但是實際執行會是從右到左這樣?
這個我剛剛看到了一個大神的講解挺好的(正在查資料核對),對象的連等賦值,大概解釋是這樣的:foo.x = foo = { b: 3 },在解釋器執行中先看foo.x 和foo是否已經創建如果未創建就創建它並且將他們都指向最右邊的對象,明顯foo創建了並且指向{ a: 2 },foo.x還未創建,於是創建它並且讓它指向null,此時bar和foo都指向{a:2,x:null},再將他們都指向右邊的物件{b:3},此時bar指向{a:2,x:{b:3} },foo指向{b:3};
最近剛討論過這個問題,我們得出的結論是:
foo.x
中的foo
实际是对{ a: 2 }
的一個引用,但執行順序還是從右到左的,這點沒有疑問。賦值,是一個表達式,
結合性從右往左,即
a = b = c
是a = (b = c)
a = b = c
是a = (b = c)
返回值是,等号右边那个表达式的返回值,即
b = c
的返回值是c
回傳值是,等號右邊那個表達式的回傳值,也就是b = c
的回傳值是c
的值。局部左到右(.),宏觀右到左(=)。此 foo 非彼 foo 。
讀到第二個 foo 時,已經從第一個 foo 取得了
{ a: 2 }
的引用,等待給其 x 屬性賦值。賦值是從右到左的,但執行之前必然對代碼進行處理,
foo.x = foo = { b: 3 }
,对属性的处理是按值进行的,即此时已经定位到了{ a: 2 }
這個對象的實際存儲位置,對屬性x的賦值也是對實際對象的x屬性賦值,不管他是foo指向的對象,還是bar指向的對象。物件的賦值是改變該物件儲存的實際物件的位址,即修改了foo的指向。我覺得這種寫法沒什麼意義。
在實際生產中,要是遇到很多這樣的程式碼,你能一眼明白嗎?
就像現在,前面答題的,有多少能夠通俗的說明白?
/a/11...
但是實際上按順序執行上面三條語句,結果會有所不同,因為foo.x是在解析階段已經準備好的,所以實際上指向的是bar.x
實際上的等價代碼
可以使用指標來理解這個問題