TypeScript中Getter/Setter用法详解

作者:代码拾荒

时间:2026-10-31

浏览:123

本文深入解析TypeScript中Getter和Setter的使用场景与潜在问题。通过具体代码示例,探讨了赋值行为与方法调用的混淆、IDE自动重构带来的下划线前缀困扰,以及访问修饰符下的特殊性。同时分析了Getter/Setter在数据拦截和前后端转换中的优势,帮助开发者权衡使用策略。

文章目录

一、写在前面

第一天

开篇声明,先观察以下代码,尝试在脑海中编译运行:No errors, no warnings!

const config = new Config()
config.version = '1.0.0'
console.log(config.version)

初看之下,这段代码似乎会输出 1.0.0,不妨实际运行验证:

一、写在前面

接着查看 Config 类的具体实现,结果令人惊讶

export class Config {
  private _version!: string

  public get version(): string {
    return this._version
  }

  public set version(value: string) {
    this._version = '莫挨劳资'
  }
}

原来是 getter/setter 机制在起作用!这表明 config.version = '1.0.0' 并非直接为 Config 的 version 字段赋值,而是触发了 version 的 set 方法。

对此我持保留态度,这种设计增加了认知负荷,使得赋值操作与方法调用难以直观区分,必须深入源码才能明确其行为。

第二天

若再次询问上述问题的答案,我将不再确信。

随之而来的第二个疑问是:

const user = new User()
user.name = '彭于晏'
user.age = 33
user.length = '15cm'
console.log(JSON.stringify(user))

基于我丰富的生活经验,这显然是在将 JSON 序列化为字符串。无需多言,脑海中编译运行的结果必然是:

{"name":"彭于晏","age":33,"length":"15cm"}

鉴于昨日的教训,今日仍需实际运行验证结果:

一、写在前面

唉,这消息是如何泄露的?

心中不服,再次深入 User 类探究真相,不看则已,一看之下令人咋舌~

export class User {
  /**
   * # 昵称
   */
  private nickname!: string

  public get name(): string {
    return this.nickname
  }

  public set name(value: string) {
    this.nickname = 'Hamm'
  }

  /**
   * # 年龄
   */
  private year!: number

  public get age(): number {
    return this.year
  }

  public set age(value: number) {
    this.year = 22
  }

  /**
   * # 长度
   */
  private len!: string

  public get length(): string {
    return this.len
  }

  public set length(value: string) {
    this.len = `${parseInt(value.replace('cm', '')) + 3}cm`
  }
}

究竟是谁设计的!做得太妙了!!!

上述剧情均为真实案例,若有雷同,说明你同样敏锐!

二、我不太喜欢Getter和Setter

1. vscode自动重构的属性名带下划线

vscode 提供了属性一键自动生成 getter/setter 的功能,为防止属性名与方法名冲突,系统会自动生成一个前缀加下划线的新属性,并移除原属性,同时生成 get set 两个方法。

一、写在前面

生成的最终代码结构如下图所示

一、写在前面

尽管在生成过程中允许指定自定义属性名,但我对此深感困扰;若使用默认设置,我的 eslint 规则又会报错,认为属性名不符合规范……

一、写在前面

2. 调用方的心智负担

如下面之前贴过的代码:

const config = new Config()
config.version = '1.0.0'
console.log(config.version)

在未阅读 Config 类源码的情况下,调用者会主观认为 config.version = "1.0.0" 是在给属性赋值,而调用 let version = config.version 则是取出刚才赋的值。

3. Get/Set方法和普通方法区别对待

在存在 private protected public 等访问修饰符的前提下,类本身拥有的属性、方法及构造器已足以满足需求。此处非要引入 get set 这种连写法都需特殊对待的方法形式,构造方法 constructor 表示强烈不满,既然它未受特殊对待,为何 get/set 要享受特权?

4. 我理解的属性

属性应被视为类中最基础的数据存储单元,存入属性的值与取出的值必须完全一致:

老张,我这瓶水暂放你这,稍后我来取。

此处我实际上执行了对老张的赋值操作。因此,稍后回来取回的水,理应还是那瓶水:

const store = new Store()
store.water = "哇哈哈"

// a few moments later

console.log(store.water) // 哇哈哈

因此,上面的输出结果必须为 哇哈哈 才符合逻辑,第一天遇到的异常情况本不应存在。

5. 我理解的方法

方法应视为类中 委托事项流程 的整合体,无论是普通方法,还是get/set,亦或是 构造方法。

其中构造方法较为特殊,且应是整个类中唯一的特殊存在。

get / set 方法仅是从规范层面形成的约定俗成的方法,既然属于方法,get / set 的调用都应加上 括号 (),以增强可读性。此外,方法名与属性名并非绝对不可重复。

三、Getter/Setter的优势

简要阐述几点。

1. 数据拦截

利用 get set 方法实现数据拦截,本文不再赘述,可参考部分前端框架的双向数据绑定实现以深入学习。

2. 数据转换

在前后端数据转换场景中,除我们此前使用的 基于装饰器-我是这么处理TypeScript项目数据转换的 方案外,利用 get set 进行数据转换或许也是极佳的选择(当然,属性名 与 get/set 不重复的问题,仍值得进一步探讨)。

以上就是TypeScript中Getter/Setter用法详解的详细内容,更多关于TypeScript Getter/Setter的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章