简体   繁体   中英

How to create a deep frozen version of an object without mutating the original?

Let's say we have the following object:

"use strict"; // To trigger errors on frozen objects mutation attempts

const myObj = {
  rootProp1: {
    leafProp1: "hello",
    leafProp2: "world",
  rootProp2: "!",
};

When using the "classic" Object.freeze method, we only freeze the root properties of an object:

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

In order to deep freeze the object, we can use a method like this one :

const deepFrozen = deepFreeze(myObj);

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

But that's still a problem for me: I would like a function that can return the frozen version of an object, without freezing the original one (I'm trying to learn functional programming so I want as less mutations as possible). How to do that?

In ECMAScript 2018 (ES9), thanks to the spread operator , it's possible to use this simple function:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM