情节:
我有一个名为myVar
的 protected 变量,它的结构和数据由构造函数定义,例如
this.myVar = this.legacy ? this.legacy.listing : this.default;
当您编辑myVar
时,它也会更改this.default
结构和数据。所以我的问题很简单:如何保持 this.default
不可变?
感谢任何帮助,
PS:诸如此类的函数
private default = (): Structure[] => {
return [{
param1: 'param1'
}]
}
这不是我的目标。
最佳答案
tl;dr:您需要使 myVar
和您的默认结构成为不同的对象。 readonly
不是解决方案。
readonly
不是解决方案
readonly
对您尝试执行的操作没有帮助。如果您在 number
或 string
等基本类型上使用 readonly
,则该字段实际上是不可变的。但是,保存 Object
(及其派生类,如 Function
和 Array
)的字段包含对目的。 readonly
使引用不可变,而不是对象本身。这与const
完全相同。这是一个使用 const 的示例:
class Structure {
public prop: number = 1;
}
const a: Structure = new Structure();
console.log(a.prop);
a.prop++; // It does not matter that `a` was marked `const`.
console.log(a.prop);
上面的代码将显示:
1
2
我们已经能够改变a
,即使它是只读的。
现在,这是一个 readonly
的示例:
class Structure {
public prop: number = 1;
}
class Something {
// This is the analogue to `default` in your question. I don't like
// the name default because it is a keyword and looks funky here in
// syntax highlighting.
private static readonly defaultStructure = new Structure();
readonly myVar: Structure;
constructor() {
this.myVar = Something.defaultStructure;
}
doSomething() {
this.myVar.prop++;
}
// `readonly defaultStructure` prevents this:
// evil() {
// Something.defaultStructure = new Structure();
// }
}
const something = new Something();
console.log(something.myVar);
something.doSomething();
const somethingElse = new Something();
console.log(somethingElse.myVar);
这显示:
Structure { prop: 1 }
Structure { prop: 2 }
我们已将 myVar
和 defaultStructure
设为只读,但修改 myVar
会修改 defaultStructure
反对:“但是,Louis,你这个大笨蛋,你应该将 prop
设置为只读!”
不,如果我设置 prop
readonly
那么我就不能再修改 myVar
了,但我希望能够修改 myVar
!
好的,现在怎么办?
最终,无论使用多少 readonly
或装饰器或 Object.freeze
都无法满足您的需求。只要 myVar
和 defaultStructure
都引用同一个对象,您就可以 a) 通过 myVar
改变 defaultStructure
code>,或 b) 如果您使 defaultStructure
指向的对象不可变,您也会使 myVar
指向的对象不可变,因为它们是相同的对象。。 您需要使 myVar
和您的默认结构是不同的对象。
为此,您有几种选择:
您可以重新构造
myVar
,而不是从默认值进行分配。您在问题中展示了一个这样的示例,并表示您没有瞄准或那样的目标,但这是一个有效的选项。您可以将默认结构的克隆分配给
myVar
。克隆对象的方法有很多种。一般情况下,需要深拷贝。有许多用于深度复制的库。您应该研究什么最适合您的具体情况。
在这种情况下,在这两种情况下,我更喜欢选项 1,因为我知道默认结构必须包含什么。当我必须获取可以具有多个不同值的结构的副本时,我会使用克隆。
关于javascript - TypeScript 中的不可变数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39762871/