菜雞前端回覆《友好"挑戰"掘金全體前端》

寫在前面

最近偶然逛掘金,看到了一篇討論特別火的文章,主要問題以下前端

var a = {n: 1};

var b = a;  

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

console.log(a);
console.log(a.x)
console.log(b);
console.log(b.x);
複製代碼

輸出的結果是什麼?程序員

相信知道結果的人不在少數,可是做爲一個菜雞前端開發來講,只是想作的或者說應該作的是在本身知識基礎上嘗試性的解釋下這個問題,其餘的並不敢妄斷。若有解釋不對的地方,但願各位指出,幫助我更加深刻的理解面試

昨天跟公司的大佬也face to face交換了一下思路,發現本身要學的還真是特多的。bash

正文

首先說一下,我在工做中沒有見到過這種寫法(固然不排除,個人層次不足)。spa

程序員所生產的代碼是給人看給機器執行的,這種寫法有點反人類,並非那麼容易維護,review的時候很痛苦,想在幾百上千行中注意到這樣的語句仍是比較麻煩的。3d

在個人理解中這個更像一個考題,來考察面試者的知識點。那既然說到了知識點,咱們言歸正傳好了,來講說這個題目。code

JS中基礎類型和引用類型

下面來講說這兩種類型的存儲cdn

棧內存(stack)
var a = 1 
複製代碼

基礎數據類型存儲在棧內存中對象

如上,定義一個變量a,系統自動分配存儲空間(棧內存)。按值訪問,所以咱們能夠直接操做保存在棧內存中的值。blog

堆內存(heap)
var a = { n : 1 }
複製代碼

須要明確的是引用數據類型的值存儲在堆內存中。上面咱們生成的變量a 其實保存在棧中, a的值就是指向堆中{n:1}的內存地址

有了這些基礎咱們把問題拆解開:

第一部分

var a = {n: 1};
var b = a;  
複製代碼

忽略難看的因素

其實是將棧中a存儲的堆內存地址賦值給了b。

第二部分

a.x = a = {n: 2};
複製代碼

這部分須要注意的是優先級

'.'的優先級大於賦值,因此最早執行的是a.x,再執行賦值操做,賦值操做是右結合的,因此以下:

最早執行的a.x能夠看作是 a.x = undefined;

而後進行賦值操做, 可是須要注意,由於先執行的a.x = undefined;,a.x中的a已是對堆中對象{n:1,x:undefined}的引用

a={n:2}
複製代碼

將棧中保存的a變量指向新的引用類型

忽略難看手稿

而後是

a.x = a;
複製代碼

前面已經說過了,因爲優先級的緣由a.x中的a已經完成了對堆內存中對象的引用,指向的是{n:1,x:undefined}(地址是0x6789),並非更改以後a的值(0x8889), 賦值操做能夠變形爲 b.x = a;

因此輸出結果

寫在最後

文章有粗陋淺薄之處,請各位大神斧正

我以爲提出疑問你們談論沒太大的問題,畢竟掘金是你們交流的地方,也有不少優秀大佬願意幫助別人。

更重要的應該是關注問題的自己和問題背後隱藏的問題,提升本身、幫助他人。不要太在乎其餘東西,有些東西本身明白就行了,永遠沒法叫醒一個裝睡的人,不是嗎?

掘金會越辦越好的,風氣也會愈來愈好。你們加油

相關文章
相關標籤/搜索