包含只读对象的扩展运算符
spread operator for object containing readonly
我的样本class:
class Foo {
private static counter = 1;
readonly id: number;
constructor() {
this.id = Foo.counter++;
}
}
我有两个选择:
- 让构造函数接受另一个
Foo
,这样我就可以使用 new Foo(foo)
进行克隆
- 制作
id
public,以便我可以使用 { ...foo }
进行克隆
有没有办法使用传播克隆并保留 readonly
(或任何阻止 id
从外部修改的东西)?
Is there anyway to use spread clone AND keep readonly
...
没有。 { ...foo }
的结果是一个具有 read/write public 数据属性的普通对象,用于 foo
自己的可枚举属性。您无法在 class 中添加任何内容来改变该行为。
另请注意,由于 { ...foo }
创建了一个普通对象,它将不再是 Foo
的实例。例如,如果 Foo
定义了任何方法,克隆将不会拥有它们。 (在问题的代码中,那种克隆将是 assignment-compatible 和 Foo
因为它 没有 定义任何方法。但是如果 Foo
有方法,但不会。)
如果你想使用扩展语法(它不是运算符)来克隆对象,不要使用class
,使用interface
因为克隆不会继承 class 将分配的原型。
在这种情况下,如您所说,您可以使 Foo
的构造函数可选 copy-constructor:
class Foo {
private static counter = 1;
readonly id: number;
constructor(other?: Foo) {
if (other) {
// Copying
this.id = other.id; // Just to make TypeScript happy that `id` is
// definitely assigned on this path (it would be
// anyway, but TypeScript doesn't know that)
Object.assign(this, other);
} else {
// Creating a new one
this.id = Foo.counter++;
}
}
}
(而不是 this.id = other.id;
行,我们 可以 用“明确分配”注释 [readonly id!: number;
] 标记 id
。但是由于构造函数有多个路径,我不会这样做,因为在修改代码时太容易忘记它。所以我会使用上面不必要的赋值。)
我的样本class:
class Foo {
private static counter = 1;
readonly id: number;
constructor() {
this.id = Foo.counter++;
}
}
我有两个选择:
- 让构造函数接受另一个
Foo
,这样我就可以使用new Foo(foo)
进行克隆
- 制作
id
public,以便我可以使用{ ...foo }
进行克隆
有没有办法使用传播克隆并保留 readonly
(或任何阻止 id
从外部修改的东西)?
Is there anyway to use spread clone AND keep
readonly
...
没有。 { ...foo }
的结果是一个具有 read/write public 数据属性的普通对象,用于 foo
自己的可枚举属性。您无法在 class 中添加任何内容来改变该行为。
另请注意,由于 { ...foo }
创建了一个普通对象,它将不再是 Foo
的实例。例如,如果 Foo
定义了任何方法,克隆将不会拥有它们。 (在问题的代码中,那种克隆将是 assignment-compatible 和 Foo
因为它 没有 定义任何方法。但是如果 Foo
有方法,但不会。)
如果你想使用扩展语法(它不是运算符)来克隆对象,不要使用class
,使用interface
因为克隆不会继承 class 将分配的原型。
在这种情况下,如您所说,您可以使 Foo
的构造函数可选 copy-constructor:
class Foo {
private static counter = 1;
readonly id: number;
constructor(other?: Foo) {
if (other) {
// Copying
this.id = other.id; // Just to make TypeScript happy that `id` is
// definitely assigned on this path (it would be
// anyway, but TypeScript doesn't know that)
Object.assign(this, other);
} else {
// Creating a new one
this.id = Foo.counter++;
}
}
}
(而不是 this.id = other.id;
行,我们 可以 用“明确分配”注释 [readonly id!: number;
] 标记 id
。但是由于构造函数有多个路径,我不会这样做,因为在修改代码时太容易忘记它。所以我会使用上面不必要的赋值。)