TypeScript:为什么 readonly 与数组的工作方式如此不同?

问题描述 投票:0回答:1

这是一个简单的类示例,我在其中以不同的方式声明了两个数组:

  1. 只读 arr: string[];
  2. arr2:只读数组
class ReadonlyArrsClass {
  readonly arr: string[] = ['1', '2'];
  arr2: ReadonlyArray<string> = ['1', '2'];

  addToArr(): void {
    this.arr.push('333'); // okay.
  }

  addToArr2(): void {
    this.arr2.push('444'); // error!
  }

  changeArrData(): void {
    this.arr = ['555']; // error!
  }
  changeArr2Data(): void {
    this.arr2 = ['666']; // okay.
  }

   logToConsole(): void {
    console.log(this.arr);
    console.log(this.arr2);
  }

  constructor(){
    this.addToArr();
    this.addToArr2();
    this.logToConsole();
    this.changeArrData();
    this.changeArr2Data();
    this.logToConsole();
  }
}

new ReadonlyArrsClass;

为什么在情况1中,我仍然可以使用push()将元素添加到

arr
的末尾?

但如果是第2种情况,我就不能。 (这似乎更符合逻辑)。我收到错误属性“push”在类型“readonly string[]”上不存在。


为什么在情况2中。我可以重新分配

arr2
的引用?

但在情况 1 中,我收到错误 - 无法分配给“arr”,因为它是只读属性。


有人可以解释为什么会这样工作以及最好使用什么🤷🏻?

或者根本不使用它🙈

typescript readonly
1个回答
0
投票

所以我明白了:分开是必要的

  • readonly arr
  • string[]
  • ReadonlyArray<string>

然后你就会清楚其中的区别。

当您使用

readonly arr
时,我们正在谈论一个对象,如果您初始化它,则无法更改它(包括其类型)。也就是说,您无法重新分配新数组,但可以推入旧数组。

当您使用

string[]
ReadonlyArray<string>
时,我们只讨论类型,并且只有类型负责行为 - 在这种情况下,如果 arr 没有
readonly
,那么您可以创建并分配新对象。

在使用方面,你需要了解任务需要什么:

  1. readonly arr: ReadonlyArray<string>
    - 本质上是您定义的常量,您不能以任何方式更改,既不能分配新对象(更改引用),也不能推送它。
  2. arr: ReadonlyArray<string>
    - 您可以分配一个新数组,但不能推送。
  3. readonly arr: string[]
    - 您可以推送,但不能分配新数组。

然后,根据任务,您选择要使用的内容:

  • 如果您定义了需要补充的集合,请选择选项 3。
  • 如果您想重新分配 - 选项 2。
  • 如果既不是这个也不是那个 - 选项 1。
© www.soinside.com 2019 - 2024. All rights reserved.