使用Proxy对象创建不可变的JavaScript对象
对象的可变性及其与const
关键字的关系是开发人员经常遇到的问题。通常情况下,在寻找使对象不可变的方法时,Object.freeze()
会被提出作为解决方案。我们之前已经探讨过这种方法,并详细介绍了深度冻结的解决方案。您可以在这篇文章中了解更多信息。
虽然Object.freeze()
是更直接的方法,但它并不总是最佳解决方案。特别是在处理大量对象嵌套或对象生命周期很短的情况下,使用Proxy对象可能更合适。下面是使用Proxy对象的示例:
const term = {
id: 1,
value: 'hello',
properties: [{ type: 'usage', value: 'greeting' }],
};
const immutable = obj =>
new Proxy(obj, {
get(target, prop) {
return typeof target[prop] === 'object'
? immutable(target[prop])
: target[prop];
},
set() {
throw new Error('This object is immutable.');
},
});
const immutableTerm = immutable(term);
const immutableProperty = immutableTerm.properties[0];
immutableTerm.name = 'hi'; // 报错:该对象是不可变的。
immutableTerm.id = 2; // 报错:该对象是不可变的。
immutableProperty.value = 'pronoun'; // 报错:该对象是不可变的。
虽然代理并不常见,但这段代码应该不难理解。其核心思想是使用处理程序通过set()
陷阱来阻止对对象的变异。此外,您还可以使用get()
陷阱来强制执行所有嵌套值的不可变性。这是通过检查值的类型并将代理应用于嵌套对象来实现的。
基本上就是这样。只需几行代码,您现在就可以防止对象的变异,无论其形状、嵌套程度或复杂性如何。