中的对象是可变的,无论您是否将它们定义为const变量。事实上,const在定义对象时使用只会防止变量被重新赋值。但是,您可以重新分配const对象或数组的属性,如下所示:
const myObj = { a: 10, b: 20, c: 30 };
myObj.a = 12; // { a: 12, b: 20, c: 30 };
const myArr = [15, 25, 35];
myArr[1] = 28; // [15, 28, 35];
为了使对象不可变,我们可以利用.(),这将在一定程度上防止添加新属性并防止删除和更改现有属性。然而,虽然.()提供了一些解决方案,但它只是将问题缓解到下一个嵌套级别,因为实际上它执行的是浅冻结。这意味着作为对象或数组的属性仍然可以改变:
const myObj = {
a: 1,
b: 'hello',
c: [0, 1, 2],
d: { e: 1, f: 2 }
};
.(myObj);
myObj.a = 10;
myObj.b = 'hi';
myObj.c[1] = 4;
myObj.d.e = 0;
/*
myObj = {
a: 1,
b: 'hello',
c: [0, 4, 2],
d: { e: 0, f: 2 }
*/
如您所见,.()这是朝着正确方向迈出的一步object.freeze(),但只是浅冻结了对象。为了解决这个问题object.freeze(),我们可以使用递归,检查每个属性本身是否是一个对象,如果.()是false,则应用.()到它:
const myObj = {
a: 1,
b: 'hello',
c: [0, 1, 2],
d: { e: 1, f: 2 }
};
const = obj => {
.keys(obj).(prop => {
if ( obj[prop] === '' && !.(obj[prop])) (obj[prop]);
});
.(obj);
};
(myObj);
myObj.a = 10;
myObj.b = 'hi';
myObj.c[1] = 4;
myObj.d.e = 0;
/*
myObj = {
a: 1,
b: 'hello',
c: [0, 1, 2],
d: { e: 1, f: 2 }
*/
在上面的例子中,我们应用了我们之前描述的技术来确保给定的对象被深度冻结。