创建任何对象的只读/不可变副本(包括深层属性) [英] Create a read-only/immutable copy of any object (including deep properties)

查看:85
本文介绍了创建任何对象的只读/不可变副本(包括深层属性)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在JavaScript中创建其属性无法更改的对象的只读/不可变版本?这也应适用于任何子对象的属性,等等。

How can I create a read-only/immutable version of an object in JavaScript, whose properties cannot be changed? This this should also apply to the properties of any sub objects and so on.

我遇到的所有方法都可以做到这一点( Object.defineProperty Object.freeze 等)仅适用于对象的顶级属性,而不适用于子对象。

All methods I have come across to do this (Object.defineProperty, Object.freeze, etc) work only for the top level properties of the object, but not for the sub-objects.

(一个可能的用例:在创建/修改设置配置在特定模块中键入对象,则需要以不可变的形式将其公开给程序的其余模块。)

(A possible use case: After creating/modifying a settings or configuration type object in a specific module, you need to expose it to the rest of the program's modules in an immutable form.)

推荐答案

这是我经过一番思考后想到的解决方案。可以很好地满足我的需求,所以我想分享一下QnA风格。
如果发现有任何改进/问题,请提出建议。

This is the solution I came up with after some thought. Works well for my needs so I thought I'd share it QnA style. Do suggest any improvements/issues if you you find them.

/**
 * Make the the specified object (deeply) immutable or "read-only", so that none of its
 * properties (or sub-properties) can be modified. The converted object is returned.
 * @param {object} obj Input object
 */
makeImmutable: function makeImmutable (obj) {
    if ((typeof obj === "object" && obj !== null) ||
        (Array.isArray? Array.isArray(obj): obj instanceof Array) ||
        (typeof obj === "function")) {

        Object.freeze(obj);

        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                makeImmutable(obj[key]);
            }
        }
    }
    return obj;
}

编辑:
简化了代码。现在也可以正确处理数组。

Simplified the code. Also handles arrays correctly now.

这篇关于创建任何对象的只读/不可变副本(包括深层属性)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆