iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
0
Modern Web

【這些年我似是非懂的 Javascript】系列 第 26

【這些年我似是非懂的 Javascript】Day 26 - 物件 # Part 2

今天繼續分享物件~
從陣列開始~
Let's go~


陣列

之前也有提過關於陣列的部分,
陣列也是使用 [..] 的存取型式,
但是他的組織結構不一樣的地方在於,
他是預設使用"數值索引",
例如以下範例

const arrayData = ['robin','labala','aruba'];

arrayData.length; // 3
arrayData[0]; // 'robin'
arrayData[1]; // 'labala'
arrayData[2]; // 'aruba'

因為陣列本身還是一個"物件"的關係,
所以你還是可以對他增加特性到陣列上

const arrayData = ['robin','labala','aruba'];

arrayData.foo = 'foo';

arrayData.length; // 3
arrayData[0]; // 'robin'
arrayData[1]; // 'labala'
arrayData[2]; // 'aruba'

arrayData['foo']; // 'foo'

注意你增加的特性不會影想到陣列的長度

你也可以完全不使用數值的索引,全部給他新增特性,但是這樣感覺很母湯,因為陣列本身的性為是經過最佳化處理,
如果你這樣做就像是你切肉用水果刀,
切水果用殺豬刀一樣。

複製物件

關於 JS 中如何複製一個物件是身為小菜雞一定會遇到的問題,那該是要淺層拷貝還是要深層拷貝呢?
差在哪?

  • 淺層拷貝:
    會有一個新的物件,除了純值外的都只會複製參考。
  • 深層拷貝
    我全都要,我全都複製。

聽起來滿好瞭解和釐清的啊!
但是... 下面這蛋疼的範例你先看看。

function foo(){/*..*/}

const bar = {
    a: true
};

const baz = [];

const obj ={
    b: 2,
    c: bar, // 參考
    d: baz, // 參考
    e: foo
};

baz.push(bar,obj)

所以我說 obj 的拷貝值是淺層還是深層 xD?
如果是淺層拷貝 b 會在新的物件裡新增一個複製,但是 cde 特性還是原本的參考,所以說不過去啊!

那如果是深層拷貝,他不只會複製 obj ,他還會複製 barbaz,但是 baz中又還是有對 objbar 的參考,這樣無限的循環複製的問題稱之為循環參考。

看完是不是覺得...

貴圈真亂。

書中提道在 JS 中的框架都選擇了各自的解決方法,並沒有統一的標準...

所以我們該如何去解決他?
可以使用
JSON-safe 物件你就可以輕易的被複製起來了。
(簡單來說就是先變成字串再變回物件)

const newObj = JSON.parse(JSON.stringify(obj));

ES6 定義了 Object.assign(..),而這個東西他可以接收一個物件當第一個參數,接著後續參數作為來源。
並且他會將來源的東西複製到那個目標上,並且回傳該目標。

const newObj = Object.assign({}, obj);

newObj.b; // 2
newObj.c === bar; // true
newObj.d === baz; // true
newObj.e === foo; // true

以上是今天的內容
(還真少 Orz)
連假是魔鬼QQ,
今天原本的內容會併在明天所以理論上來說明天內容會比較多一點xD
"希望"可以在三十天內至少看完這本。


參考來源:

你所不知道的 JS|範疇與 Closures,this 與物件原型 (You Don't Know JS: this & Object Prototypes))


上一篇
【這些年我似是非懂的 Javascript】Day 25 - 物件 # Part 1
下一篇
【這些年我似是非懂的 Javascript】Day 27 - 物件 # Part 3 # 特性描述器
系列文
【這些年我似是非懂的 Javascript】34

尚未有邦友留言

立即登入留言