You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中特定getter/setter的工作原理及底层值疑问

Understanding TypeScript Getters/Setters and Their Compiled Output

Great question! Let's break this down step by step to clear up the confusion around how these getters/setters work, what their underlying values are, and why you don't see that var _prop declaration in the compiled ES2015 code.

First: The Critical Issue with this.prop in Both Getter and Setter

If you’ve written code where both the getter and setter reference this.prop directly (like the example below), you’re running into a fatal problem: infinite recursion.

class BadExample {
  get prop() {
    return this.prop; // ❌ Triggers the getter again... infinitely
  }
  set prop(value) {
    this.prop = value; // ❌ Triggers the setter again... infinitely
  }
}

Every time you try to read instance.prop, the getter fires, which tries to read this.prop again—looping forever. Same goes for assignment: setting instance.prop = "foo" triggers the setter, which tries to assign to this.prop, firing the setter once more. This will crash your code with a stack overflow error.

The Correct Approach: Underlying Storage Variables

To make getters/setters work properly, you need a separate underlying storage variable to hold the actual value. This is almost always a private variable (conventionally prefixed with an underscore like _prop, or using TypeScript’s true private fields with #).

Here’s the fixed version:

class GoodExample {
  // Private storage variable (compiled to a regular instance property in ES2015)
  private _prop: string;

  get prop() {
    return this._prop; // ✅ Reads the actual stored value
  }
  set prop(value: string) {
    this._prop = value.trim(); // ✅ Writes to storage (with optional logic!)
  }
}

In this case, this._prop is the real value holder. The getter just returns it, and the setter can add logic (like trimming whitespace) before updating it.

Why No var _prop in the Compiled ES2015 Code?

When TypeScript compiles this to ES2015, you’ll end up with code like this:

class GoodExample {
  get prop() {
    return this._prop;
  }
  set prop(value) {
    this._prop = value.trim();
  }
}

You won’t see a var _prop declaration here because _prop is an instance property, not a local variable. Here’s why:

  • Instance properties are attached to the class instance (via this) when they’re first assigned. When you run this._prop = value, JavaScript automatically creates the property on the instance if it doesn’t exist yet.
  • Local variables (declared with var, let, or const) are scoped to a function or block, but _prop needs to persist across multiple calls to the getter/setter—so it has to live on the instance itself.

If you initialized _prop in the constructor (e.g., this._prop = "default"), you’ll see that assignment in the compiled constructor, but still no var declaration—because again, it’s an instance property, not a local variable.

Bonus: True Private Fields (ES2022+)

If you use TypeScript’s true private fields (with #), like this:

class TruePrivateExample {
  #prop: string; // Native private field

  get prop() {
    return this.#prop;
  }
  set prop(value: string) {
    this.#prop = value;
  }
}

The compiled ES2022 code will use JavaScript’s native private field syntax (#prop), which is enforced by the engine—no way to access it from outside the class. You still won’t see a var declaration here, since it’s a class-level private field.

To Sum Up

  • Never use this.prop directly in both getter and setter—it causes infinite recursion. Always use an underlying storage variable.
  • The _prop (or #prop) in compiled code is an instance property, not a local variable, so you won’t see a var declaration for it. It’s created automatically when you first assign to this._prop.

内容的提问来源于stack exchange,提问作者keldar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:13:24