W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
var a = {n:1};
a.x = a = {n:2};
alert(a.x); // --> undefined
看 jQuery 源碼 時發(fā)現(xiàn)的這種寫法。
以上第二句 a.x = a = {n:2}
是一個連續(xù)賦值表達(dá)式。
這個連續(xù)賦值表達(dá)式在引擎內(nèi)部究竟發(fā)生了什么?是如何解釋的?
猜想1:從左到右賦值,a.x
先賦值為 {n:2}
,但隨后 a 賦值為 {n:2}
,
即 a 被重寫了,值為 {n:2}
,新的 a 沒有 x 屬性,因此為 undefined
。
步驟如下
a.x = {n:2};
a = {n:2};
這種解釋得出的結(jié)果與實(shí)際運(yùn)行結(jié)果一致,貌似是對的。
注意「猜想1」中 a.x 被賦值過。
猜想2:從右到左賦值,a 先賦值為 {n:2}
,a.x
發(fā)現(xiàn) a 被重寫后(之前 a 是 {a:1}
),
a.x = {n:2}
引擎限制 a.x
賦值,忽略了。
步驟如下:
a = {n:2};
a.x 未被賦值{n:2}
等價于 a.x = (a = {n:2})
,即執(zhí)行了第一步,這樣也能解釋 a.x
為 undefined
了。
注意「猜想2」中 a.x 壓根沒被賦值過。
上面兩種猜想相信多數(shù)人都有,群里討論呆呆認(rèn)為是「猜想1」, 我認(rèn)為是「猜想2」。其實(shí)都錯了。 我忽略了引用的關(guān)系。
如下,加一個變量 b,指向 a。
var a = {n:1};
var b = a; // 持有a,以回查
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> [object Object]
發(fā)現(xiàn) a.x
仍然是 undefined
,神奇的是 b.x
并未被賦值過(比如:b.x={n:2})
,卻變成了 [object Object]
。
b 是指向 a({n:1})
的,只有 a.x = {n:2}
執(zhí)行了才說明b是有x屬性的。
實(shí)際執(zhí)行過程:從右到左,a 先被賦值為 {n:2}
,隨后 a.x
被賦值 {n:2}
。
a = {n:2};
a.x = {n:2};
等價于
a.x = (a = {n:2});
與猜想2的區(qū)別在于 a.x
被賦值了,猜想2中并未賦值。
最重要的區(qū)別,第一步 a = {n:2}
的 a 指向的是新的對象 {n:2}
, 第二步 a.x = {n:2}
中的 a 是 {a:1}
。
即在這個連等語句
a.x = a = {n:2};
a.x 中的a指向的是 {n:1}
,a 指向的是 {n:2}
。
a.x = a = {n:2}
│ │
{n:1}<──┘ └─>{n:2}
這篇寫完,或許部分人看完還是暈暈的。 因?yàn)槔锩娴奈淖置枋鰧?shí)在是繞口。
最初我在理解這個連等賦值語句時
var a = {n:1};
a.x = a = {n:2};
認(rèn)為引擎會限制 a.x
的重寫(a 被重寫后),實(shí)際卻不是這樣的。
指向的對象已經(jīng)不同了。引擎也沒有限制 a.x={n:2}
的重寫。
呵,以另一個連續(xù)賦值題結(jié)束。 fun 執(zhí)行后,這里的 變量 b 溢出到 fun 外成為了全局變量。
想到了嗎?
function fun(){
var a = b = 5;
}
fun();
alert(typeof a); // --> undefined
alert(typeof b); // --> number
原文:http://justjavac.com/javascript/2012/04/05/javascript-continuous-assignment-operator.html
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: