定義物件
除了原始型別以外,都是物件 ! 例如:array、function 等
一般我們常用到的物件是用 {} 包裹,內含 key 與對應的 value 組成
key 可使用能轉換為 string 的值、Symbol 型別,value 可以是任意的
const symbol = Symbol('symbolKey');
const obj = {
0: 'zero',
'zero': 0,
[symbol]: 'symbolValue',
}
取值
const user = {
name: 'John',
age: 30
}
console.log(user.name); // John
const prop = 'age';
console.log(user[prop]); // 30
傳值
當我們將物件賦值給變數時,實際上是指向該物件的記憶體位置,而不是創建一個新的物件 ( call by reference )。也就是說,如果更改物件的的屬性,被賦值的變數也會進行更改。
const obj1 = {
name: 'John',
age: 30
}
const obj2 = obj1;
obj2.age = 18;
console.log(obj1); // { name: 'John', age: 18 }
console.log(obj2); // { name: 'John', age: 18 }
淺拷貝 ( shallow clone )
怎樣避免上述的狀況呢,我們可以創建一個新的物件。
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = Object.assign({}, obj1);
const obj3 = { ...obj1 };
為什麼叫淺拷貝呢? 因為使用這種方式我們雖然創建了新的物件,但新物件內 value 的物件參考還是會跟原始物件共享,所以改變 value 內的物件時,還是會同樣受影響。
// 承接上一個範例
obj2.b.c = 5
console.log(obj1); // { a: 1, b: { c: 5 } }
console.log(obj2); // { a: 1, b: { c: 5 } }
深拷貝 ( deep clone )
如果創建一個新的物件且新物件跟原始物件不共享 value,做到完全的不受影響,這就是深拷貝。
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = JSON.parse(JSON.stringify(obj1));
但這個方法因為 JSON 本身的限制在某些情況會有問題
- undefined ⇒ 忽略
- function ⇒ 忽略
- 循環引用 ⇒ 報錯
const obj1 = {
a: 1,
b: {
c: 3,
d: undefined,
e: () => {}
}
};
const obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2); // { a: 1, b: { c: 3 } };
const obj1 = {
a: 3,
b: {}
}
obj1.b = obj1;
const obj2 = JSON.parse(JSON.stringify(obj1));
// Uncaught TypeError: Converting circular structure to JSON
為了避免這個問題我們可以使用第三方的 library
例如:lodash ( https://lodash.com/docs/4.17.15#cloneDeep )
Map
是 key-value 的集合,key 在 Map 中是唯一的
Map vs Object
Map | Object | |
---|---|---|
意外的 Key 值 | Map 沒有額外的 key,只有實際放入的 key | 物件有從原型鏈帶來的 key,有可能發生衝突 |
安全性 | 使用 user 輸入的內容當 key-value 是安全的 | 使用 user 輸入的內容當 key-value 有可能覆寫物件原型鏈,造成 object injection attacks |
Key 的型別 | Map 的 key 可以是任意值 ( 函式、物件、原始型別等 ) | 物件的 key 要是 String or Symbol |
Key 的順序 | Map 是有序的,依照加入的順序 | 物件的 key 目前是有序的,按照固定的順序 |
有多少 key-value pair | 直接取用 size | 透過 Object.keys(obj).length 取得 |
迭代 | Map 是可以直接迭代的 | Object 是不可以直接迭代的,通常透過 for … of 處理 |
效能 | 有針對頻繁的加入、移除 key-value pairs 做最佳化 | 沒有針對頻繁的加入、移除 key-value pairs 做最佳化 |
序列化和解析 | 沒有原生支援 | JSON.stringify()、JSON.parse() |
Set
儲存不重複的值,值可以是原始型別或物件
Top comments (0)