奇特的JavaScript連續賦值運算

2021-09-07 15:22:14 字數 1830 閱讀 8375

一、引子:

var a = ;

a.x = a = ;

alert(a.x);

//--> undefined

以上第二句 a.x = a = 是乙個連續賦值表示式。這個連續賦值表示式在引擎內部究竟發生了什麼?是如何解釋的?

二、猜想

猜想1:從左到右賦值,a.x 先賦值為,但隨後 a 賦值為 ,即 a 被重寫了,值為 ,新的 a 沒有 x屬性,因此為undefined。步驟如下

1, a.x = ;

2, a = ;

這種解釋得出的結果與實際執行結果一致,貌似是對的。注意猜想1中 a.x 被賦值過。

猜想2:從右到左賦值,a 先賦值為,a.x 發現 a 被重寫後(之前a是),a.x = 引擎限制a.x賦值,忽略了。步驟如下:

1, a = ;

2, a.x 未被賦值

等價於 a.x = (a = ),即執行了第一步,這樣也能解釋a.x為undefined了。注意猜想2中a.x壓根沒被賦值過。

三、證明

上面兩種猜想相信多數人都有,有人認為是猜想1, 有人認為是猜想2。其實都錯了,我忽略了引用的關係。如下,加乙個變數b,指向a。

var a = ;

var b = a; //

暫存aa.x = a = ;

alert(a.x);

//--> undefined

alert(b.x);//

--> [object object]

發現 a.x 仍然是undefined,神奇的是 b.x 並未被賦值過(比如:b.x=),卻變成了[object object]。b 是指向 a()的,只有a.x = 執行了才說明 b 是有 x 屬性的。

實際執行過程:從右到左,a 先被賦值為,隨後a.x被賦值。等價於:a.x = (a = );  與猜想2的區別在於 a.x 被賦值了,猜想2中並未賦值。

最重要的區別,第一步 a = 的 a 指向的是新的物件 , 第二步 a.x = 中的 a 是

即在這個連等語句中,a.x 中的a指向的是 ,a 指向的是 。如下圖:

四:解惑

這篇寫完,或許部分人看完還是暈暈的,因為裡面的文字描述實在是繞口。最初我在理解這個連等賦值語句時,認為結果為:,實際卻不是這樣的。

a指向的物件已經不同了,引擎也沒有限制a.x的重寫。

var a = ;

var b =a;

a.x = a = ;

console.log(a,a.x);

console.log(b);

//object undefined

//object object

理解:第乙個a.x的a就近原則,指向的是第一行宣告的a;console.log(a.x)裡的a.x相當於a被重新賦值,就近原則,a指向的是,並沒有x屬性,故為undefined。五:結束

以另乙個連續賦值題結束。fun執行後,這裡的 變數 b 溢位到fun外成為了全域性變數。想到了嗎?

思考

:要記住這種連續賦值,後面的變數是一種隱式宣告即可。

function fun()

fun();

console.log(a);

//--> 報錯:a is not defined

console.log(b); //

--> 5

奇特的音效卡故障

一位朋友的 在宣判音效卡死刑時又了解了一下電腦的配置及使用情況。賽揚500 開機時顯示 64mb的kingmax記憶體,同維p6bf zx 主機板,tnt2 m64顯示卡,火球九代10gb硬碟。電腦一直使用正常,出現故障的前幾天曾有乙個電腦高手來玩過。電腦高手會不會改變了什麼設定呢?進入cmos一看...

國人的奇特心理

前幾天看汽車雜誌的時候,看見有一人從法拉利定了一台車,因為幾十萬美元的最好的限量版的enzo已經不能滿足人家的需要,而且幾百的的限量也不夠稀有,所以他以enzo為原形,拆個亂七八糟,讓法拉利重新打造了一台價值500萬美元的車。他是美國的乙個編劇。這要在我國,乙個編劇敢買個價值10萬美圓的保時捷,肯定...

C C 中奇特的宣告

首先擺乙個問題 c c 裡的兩行 int uof 3 4 int flump 3 到底定義了個什麼東東?if你很清楚,那麼你可以return 了,else 就跟著我一起看下去吧!在使用c c 程式設計的時候,經常會遇到指標和陣列,本來也沒什麼,可有時候兩者偏偏就搞到一塊,組合成指標陣列或者陣列指標之...