第 212 题:TypeScript 中 const 和 readonly 的区别?枚举和常量枚举的区别?

发布于 2022-10-21 12:24:44 字数 235 浏览 116 评论 2

readonly 标记的属性只能在声明时或类的构造函数中赋值。

之后将不可改(即只读属性),否则会抛出 TS2540 错误。

与 ES6 中的 const 很相似,但 readonly 只能用在类(TS 里也可以是接口)中的属性上,相当于一个只有 getter 没有 setter 的属性的语法糖。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

归途 2022-05-03 08:57:05

const和readonly其实是两个层面的定义。
const 定义的变量本身是readonly的,但内部属性不是

// 基本类型
const a = 1
const b = 'b'
const c = true
// const 定义的变量其值为一个基本类型,会被推导为一个字面量类型
type A = typeof a // 1
type B = typeof b // 'b'
type C = typeof c // true

// 对象
const o = {
  a: 1,
  b: 'b',
  c: true
}

type O = typeof o // { a: number; b: string; c: boolean; }

这个如果要同时使其属性变为只读,则可以使用 readonly 关键字,此时定义偏向于灵活,可以选择直接定义为字面量或者是某种类型:

interface O {
  readonly a: number;
  readonly b: 'b';
  readonly c: boolean
}

const o: O = {
  a: 1,
  b: 'b',
  c: true
}

当然,ts提供了一些语法糖来快速将对象属性变为readonly:

// 方法一:使用工具方法
interface O {
  a: number
  b: string
  c: boolean
}
type ReadonlyO = Readonly<O>

// 方法二:类型断言
const o = {
  a: 1,
  b: 'b',
  c: true
} as const // 使用 as const 进行断言

/*
type ConstO = {
    readonly a: 1;
    readonly b: "b";
    readonly c: true;
}
*/
type ConstO = typeof o
梦幻的味道。 2022-05-02 20:13:47

TypeScript 中 const 与 readonly 的区别?

TypeScript 中不可变量的实现方法有两种:

  • 使用 ES6 的 const 关键字声明的值类型
  • 被 readonly 修饰的属性

TypeScript 中 readonly

TypeScript 中的只读修饰符,可以声明更加严谨的可读属性

通常在 interface 、 Class 、 type 以及 array 和 tuple 类型中使用它,也可以用来定义一个函数的参数

// type
type Foo = {
  readonly bar: number;
};
// const 确保 'config' 不能够被改变了
const foo: Foo = { bar: 123 };
// 不能被改变
foo.bar = 456; // Error: foo.bar 为仅读属性
// 函数
function foo(config: { readonly num: number }) {
  // ..
}
const config = { num: 123 }
foo(config)

区别

  1. const 用于变量, readonly 用于属性

  2. const 在运行时检查, readonly 在编译时检查

  3. const 声明的变量不得改变值,这意味着,const 一旦声明变量,就必须立即初始化,不能留到以后赋值; readonly 修饰的属性能确保自身不能修改属性,但是当你把这个属性交给其它并没有这种保证的使用者(允许出于类型兼容性的原因),他们能改变

const foo: {
  readonly bar: number;
} = {
  bar: 123
};

function iMutateFoo(foo: { bar: number }) {
  foo.bar = 456;
}

iMutateFoo(foo);
console.log(foo.bar); // 456

此时,需要 iMutateFoo 明确的表示,他们的参数不可修改,那么编译器会发出错误警告:

function iTakeFoo(foo: Foo) {
  foo.bar = 456; // Error: bar 属性只读
}
  1. const 保证的不是变量的值不得改动,而是变量指向的那个内存地址不得改动,例如使用 const 变量保存的数组,可以使用 pushpop 等方法。但是如果使用 ReadonlyArray<number> 声明的数组不能使用 pushpop 等方法。

枚举和常量枚举的区别?

枚举和常量枚举(const枚举)

使用枚举可以清晰地表达意图或创建一组有区别的用例

// 枚举
enum Color {
  Red,
  Green,
  Blue
}

// 常量枚举
const enum Color {
  Red,
  Green,
  Blue
}

区别

  1. 枚举会被编译时会编译成一个对象,可以被当作对象使用
  2. const 枚举会在 typescript 编译期间被删除,const 枚举成员在使用的地方会被内联进来,避免额外的性能开销
// 枚举
enum Color {
  Red,
  Green,
  Blue
}

var sisterAn = Color.Red
// 会被编译成 JavaScript 中的 var sisterAn = Color.Red
// 即在运行执行时,它将会查找变量 Color 和 Color.Red
// 常量枚举
const enum Color {
  Red,
  Green,
  Blue
}

var sisterAn = Color.Red
// 会被编译成 JavaScript 中的 var sisterAn = 0
// 在运行时已经没有 Color 变量

原文

~没有更多了~

关于作者

枯寂

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文