iT邦幫忙

0

Javascript 進階 4-7 物件參考觀念的實際運作模式

這篇文章會配合Excel表來說明傳值、傳參考的特性喔!

傳值

以上一篇文章的範例來說

var person = '小明';
var person2 = person;

https://ithelp.ithome.com.tw/upload/images/20200102/20121770LbQfjvN0EJ.png

person2 = '杰倫';

https://ithelp.ithome.com.tw/upload/images/20200102/20121770D2EyehMpyN.png

傳參考

var person = {
    name: '小明'
};
var person2 = person;

https://ithelp.ithome.com.tw/upload/images/20200102/20121770v6zUum07V9.png

person2.name = '杰倫';

https://ithelp.ithome.com.tw/upload/images/20200102/20121770bz2i6SWDWH.png

那麼我們再來看看下面的例子~

var family = {
    name: '小明家',
    members: {
        father: '老爸',
        mom: '老媽',
        ming: '小明'
    }
};
var member = family.members;
member.ming = '大明';
console.log(member, family.members)

很明顯這也是一個傳參考的例子,根據上篇文章的知識我們可以知道

console.log(member, family.members) 印出來的結果 不論是 member.ming 還是 family.members.ming 都會被改成 大明,就是因為 member 被賦予的是family.members這個物件的記憶體位置。

我們再以 excel 的方式來說明~

https://ithelp.ithome.com.tw/upload/images/20200102/20121770tcmfJso9ne.png

就會像是這樣的感覺~

所以如果今天把它改成大明的話

member.ming = '大明';

https://ithelp.ithome.com.tw/upload/images/20200102/20121770CYpjCu6U2z.png

接著來一些難一點的觀念喔!

看看程式碼吧~!

var a = { x: 1 };
a.y = a;
console.log(a);

可以看到首先先物件實字定義了 var a = { x: 1 };

再定義 物件 a 裡面有一個 y 的屬性,並且把 a 他自己賦值(傳參考)到 y 這個屬性上。

最後在印出來看看 a 長怎樣

重點就是~各位會覺得發生甚麼事情呢?

我們來看看~

https://ithelp.ithome.com.tw/upload/images/20200102/20121770THsQBw8ArA.png

感覺好像打開俄羅斯娃娃,一直都是一樣的內容~

好~我們一樣來用 excel 講解這個原理喔~!

https://ithelp.ithome.com.tw/upload/images/20200102/20121770mlFrwiDZtc.png

我們就可以看到,如果今天要找 a 裡面的 y 的話,他又會找到 0x01 的自己,造成無限的循環。

這個特別的例子也其實是要強化各位對於 傳參考 這件事情的感覺。

那我們再來看看其他範例~

var a = { x: 1};
var b = a;
a.y = a = { x: 2 };
console.log(a.y);
console.log(b);

首先我們一樣定義了 var a = { x: 1};,並且定義 b 將 a 的參考(記憶體位置)傳給他。

最後定義新的物件{ x: 2 }並且重新賦值到 a 以及 a.y 上面

然後印出 a.y 以及 b

大家可以先想看看結果可能會是甚麼喔

https://ithelp.ithome.com.tw/upload/images/20200102/20121770GrrywhPZdH.png

答案如上,a.y 是 undefined,那麼 a 呢?

我們可以再找看看 a 是多少~

https://ithelp.ithome.com.tw/upload/images/20200102/20121770dHKMQvvq1F.png

他回傳我 a = {x: 2}

好~那到這裡~我們一樣再用 excel 表解釋這一切的來龍去脈!

var a = { x: 1};

https://ithelp.ithome.com.tw/upload/images/20200102/201217705ftTRDNgkg.png

var b = a;

https://ithelp.ithome.com.tw/upload/images/20200102/20121770zten4UpAKh.png

好~到這一段應該沒甚麼問題~

再來看看重頭戲!

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

這邊有三個重點

  1. a = { x: 2 } 的回傳值是 { x: 2 }, 所以不論是 a 還是 a.y 都會被賦值(傳參考) { x: 2 } 的參考。

所以可以也可以等同於 a = a.y = { x: 2 };

https://ithelp.ithome.com.tw/upload/images/20200102/20121770B94r8nnWB6.png

  1. a.y = a = { x: 2 }; 是同時執行的!!因此沒有執行順序的問題,也就是沒有因為 a 的參考先被轉成了 0x02 才進行 a.y 的賦值,沒有喔!!

是同時的,所以 a.y 才會是找原本的參考(0x01)

  1. a.y 找的是原本的參考(0x01),而不是後來的參考(0x02)

所以這裡 a.y 的賦值是在原本的參考(0x01)

https://ithelp.ithome.com.tw/upload/images/20200102/20121770w8v6tz53eD.png

最後的結果就如上圖,所以我們利用 console.log(a.y) 以及 console.log(b) 會發現

a 現在指向的是 0x02的物件,但裡面沒有 y 所以是 undefined

b 則是指向了原本 0x01 的物件,所以就照實顯示裡面的內容

所以如果我們用

console.log(a === b.y); // true

會得到的結果也是 true 的結果喔!

透過上面這些範例,了解傳參考的過程是如何運行的

總結一下重點:

  1. 連續賦值的時候會是同時執行,不會分優先順序
  2. 回傳值的內容(運算子的章節有介紹過)
  3. 參考值互換的話,尋找的參考是原本的參考值

那麼可以依照上面講述的觀念~大家來看看下面的題目

var a = { x: 1};
var b = a;
a.x = { x: 2};
a.y = a = { y: 1};
console.log(a); // 結果?
console.log(b); // 結果?

也可以利用 excel 的拆解方式~回答這個題目喔~答案公布在留言處

以上就是本章節的介紹,希望對各位有幫助~汪汪


1 則留言

0
odinhusky
iT邦新手 5 級 ‧ 2020-01-02 09:36:25

解答:

var a = { x: 1};
var b = a;

https://ithelp.ithome.com.tw/upload/images/20200102/20121770IsxzmPzeg4.png

a.x = { x: 2};
a.y = a = { y: 1};

https://ithelp.ithome.com.tw/upload/images/20200102/20121770RzbXaAXill.png

console.log(a); // 結果?
console.log(b); // 結果?

https://ithelp.ithome.com.tw/upload/images/20200102/20121770T3wKdMZdJa.png

希望有幫助大家理解 物件傳參考的觀念

沒問題的話就繼續往下走嚕~汪汪

我要留言

立即登入留言