创建任何对象的只读/不可变副本(包括深层属性)
如何在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.