如何在不改变原始对象的情况下创建对象的深度冻结版本



假设我们有以下对象:

"use strict"; // To trigger errors on frozen objects mutation attempts
const myObj = {
rootProp1: {
leafProp1: "hello",
leafProp2: "world",
rootProp2: "!",
};

当使用";经典的";Object.freeze方法,我们只冻结对象的根属性:

const frozen = Object.freeze(myObj);
frozen.rootProp2 = "?"; // error --> OK
delete frozen.rootProp1; // error --> OK
frozen.extraRootProp = "how are you?"; // error --> OK
frozen.rootProp1.leafProp1 = "hi"; // NO ERROR --> I don't want this

为了深度冻结物体,我们可以使用这样的方法:

const deepFrozen = deepFreeze(myObj);
deepFrozen.rootProp1.leafProp1 = "hi"; // error --> OK
myObj.rootProp2 = "?"; // ERROR --> I don't want this

但这对我来说仍然是一个问题:我想要一个函数,它可以返回对象的冻结版本,而不冻结原始版本(我正在尝试学习函数编程,所以我想要尽可能少的突变(。如何做到这一点?

在ECMAScript 2018(ES9(中,由于使用了排列运算符,可以使用以下简单函数:

const deepFreeze = (obj) => typeof obj === "object"
? Object.freeze({
...Object.entries(obj).reduce(
(prev, [key, value]) => ({
...prev,
[key]: value ? deepFreeze(value) : value,
}),
{}
),
})
: typeof obj === "function" ? Object.freeze(obj) : obj;

最新更新