ECMAScript 只有 Primitive 為 Immutable,Object 則為 Mutable;若要連 Object 也 Immutable,則要使用 Object.freeze()
。
Version
macOS Catalina 10.15.2
VS Code 1.41.1
Quokka 1.0.276
ECMAScript 2015
Object.freeze()
let book = {
title: 'FP in JavaScript',
price: 100,
quantity: {
Amazon: 10,
eBay: 20
}
}
Object.freeze(book)
book.price = 200
book.price // ?
book.quantity.Amazon = 30
book.quantity.Amazon // ?
ECMAScript 提供了 Object.freeze()
使 object 成為 immutable,唯只是 shallow freeze。
第二層之後的 object 仍為 mutable。
deepFreeze()
let book = {
title: 'FP in JavaScript',
price: 100,
quantity: {
Amazon: 10,
eBay: 20
}
}
let isObject = val => val && typeof val === 'object'
let deepFreeze = obj => {
if (!isObject(obj) || Object.isFrozen(obj)) return obj
Object.freeze(obj)
Object.keys(obj).forEach(x => deepFreeze(obj[x]))
}
deepFreeze(book)
book.price = 200
book.price // ?
book.quantity.Amazon = 30
book.quantity.Amazon // ?
第 10 行
let isObject = val => val && typeof val === 'object'
let deepFreeze = obj => {
if (!isObject(obj) || Object.isFrozen(obj)) return obj
Object.freeze(obj)
Object.keys(obj).forEach(x => deepFreeze(obj[x]))
}
自行實作 deepFreeze()
,若不是 object 或 object 已經被 freeze,則直接回傳 object。
除了使用 Object.freeze()
目前的 object 外,還使用 recursive 方式將第二層的 object 也 freeze。
第二層之後的 object 已經是 immutable。
Conclusion
- 雖然 ECMAScript 的 object 是 mutable,也可透過
Object.freeze()
自行實作deepFreeze()
使 object 也能 immutable
Reference
Luis Atencio, Functional Programming in JavaScript
MDN, Object.freeze()
MDN, Object.isFrozen()