【问题标题】:Difference between const and readonly in typescript打字稿中 const 和 readonly 之间的区别
【发布时间】:2017-10-04 09:13:43
【问题描述】:

打字稿中的常量与只读

将变量声明为readonly 将不允许我们覆盖,即使它们是公共属性。

const 的行为方式,

const SOME_VARIABLE:number = 10;

如果我覆盖它的值,它将如何工作?

【问题讨论】:

标签: typescript


【解决方案1】:

不能重新分配const 变量,就像readonly 属性一样。

本质上,当您定义一个属性时,您可以使用readonly 来防止重新分配。这实际上只是一个编译时检查。

当您定义 const 变量(并针对更新版本的 JavaScript 以在输出中保留 const)时,也会在运行时进行检查。

所以它们实际上都在做同样的事情,但一个用于变量,另一个用于属性。

const x = 5;

// Not allowed
x = 7;


class Example {
    public readonly y = 6;
}

var e = new Example();

// Not allowed
e.y = 4;

重要提示...“不能重新分配”与不变性不同。

const myArr = [1, 2, 3];

// Not allowed
myArr = [4, 5, 6]

// Perfectly fine
myArr.push(4);

// Perfectly fine
myArr[0] = 9;

【讨论】:

  • 我对此感到困惑 // 非常好myArr[0] = 9;。那你怎么能称它为常数呢?
  • @Aravind JS/TS 中的数组是可变对象。所以myArr 是对可变对象的常量引用。您不能将其指向其他数组,但可以更改数组的内容。你 (myArr) 捡起一个盒子 ([1, 2, 3]) 并将它粘在你的手上 (const)。胶水意味着你不能放手拿起另一个盒子 (myArr = [4, 5, 6]) 或其他任何东西 (myArr = 'something else')。但是胶水并不能阻止某人将某些东西放入盒子 (myArr.push(4)) 或替换其中的某些内容 (myArr[0]=9)。
  • Array 相同,Object 也会发生...我们有责任将它们变为不可变的 - 它们不是。
  • 只是补充一点,在 TypeScript 中你可以使用ReadonlyArray<T> 来防止推送/弹出/移位等。仅编译时,但非常适合公共库 API 等。
  • 总结:它们是相同的,但 const 用于变量,而 readonly 用于类属性。
【解决方案2】:

const 和 readonly 之间的主要区别之一在于它如何与数组一起工作。 (设备形式已经是差异) 你必须使用

readonly Array<T> 

在使用 Array 时, 其中 T 是泛型类型(谷歌了解更多)。

当您将任何数组声明为 const 时,您可以对数组执行可能会更改数组元素的操作。 例如。

const Arr = [1,2,3];

Arr[0] = 10;   //OK
Arr.push(12); // OK
Arr.pop(); //Ok

//But
Arr = [4,5,6] // ERROR

但在只读数组的情况下,您不能如上所示更改数组。

arr1 : readonly Array<number> = [10,11,12];

arr1.pop();    //ERROR
arr1.push(15); //ERROR
arr1[0] = 1;   //ERROR

【讨论】:

  • 我认为这实际上与手头的问题无关(关键字“readonly”与关键字“const”),尽管我不知道 ReadonlyArray 存在。
  • 但答案与 readonly VS const 关键字的实际行为相匹配。使用只读,您不能以任何方式修改对象/数组和对象/数组属性/元素。它主要用于状态管理系统,在这些系统中,我们只想修改纯函数集合中的值,而不是其他任何地方。
  • 它与提出的问题没有直接关系,但感谢您提供更多信息
【解决方案3】:

两者:

  • 可以更改(例如通过.push() if 数组)

常量:

  • 无法重新分配
  • 用于变量

只读:

  • 可以重新分配,但只能在构造函数中进行
  • 用于属性(类成员)

【讨论】:

  • readonly 不允许您在数组上执行.push()Property 'push' does not exist on type 'readonly any[]'. ts(2339)
  • 关于readonly 和构造函数的评论是其他答案中遗漏的关键元素。谢谢!
【解决方案4】:
  1. 我认为接受的答案没有足够强调 const 应与变量一起使用,而 readonly 与类/接口属性一起使用。

  2. readonly 仅在类型检查(编译时)期间检查,const 在运行时检查

  3. 声明一个属性为readonly并不意味着它的值不能改变:它意味着该属性不能被重新赋值,例如:


interface Person {
    readonly info: { name: string; age: number };
}

//create a new person
// ...

person.info.age += 1; // this is valid
person.info = { name: "Johnny", age: 15 }; // this is invalid!
  1. 从 TS 3.4 开始,有const assertions 用于定义types

// Type 'readonly [10, 20]'
let y = [10, 20] as const;

// Type '{ readonly text: "hello" }'
let z = { text: "hello" } as const;

欲了解更多信息,请参阅the docs

【讨论】:

    【解决方案5】:

    https://www.typescriptlang.org/docs/handbook/interfaces.html#readonly-vs-const中所说

    记住是使用 readonly 还是 const 的最简单方法是询问您是在变量还是属性上使用它。变量使用 const 而属性使用只读。

    如下图所示,如果你在定义属性时声明 const,你会得到一个错误 https://i.imgur.com/cJfDqh9.png

    【讨论】:

      【解决方案6】:

      我认为这两个词的原因可能是它比替代词更容易实现。

      例如,在 C++ 中,类可以有 const 成员。但是 C++ 有特殊的语法在构造函数运行之前初始化常量,所以从来没有真正对 const 进行任何“赋值”,比如:

      class TestClass {
          const int _x;
          TestClass(int x) : _x(x) {}
      }
      

      _x(x) 在调用构造函数之前初始化 _x 变量。

      在 Typescript 中,如果他们希望允许将成员声明为 const 并且认真对待变量为 const,则需要添加类似的语法。

      "readonly" 与 const 并不完全相同。我认为,这意味着有些不同。它的意思是“允许在构造函数内赋值,但不再允许。”

      【讨论】:

        猜你喜欢
        • 2021-09-07
        • 2011-03-05
        • 1970-01-01
        • 2021-07-29
        • 1970-01-01
        • 2018-11-05
        • 2016-08-02
        • 2012-12-16
        相关资源
        最近更新 更多