TypeScript - getOwnPropertyNames() - 构造函数属性与 Getter/Setter

JDC*_*JDC 4 reflection typescript

我对 TypeScript 很陌生,有一点我不太明白。

想象一下以下类:

export class PropertyInConstructor {

  constructor(public foo: boolean) {

  }
}
Run Code Online (Sandbox Code Playgroud)
export class PropertyWithGetSet {

  private _foo: boolean = false;

  get foo(): boolean {
    return this._foo;
  }

  set foo(theFoo: boolean) {
    this._foo = theFoo;
  }
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这两种方法都为我提供了一个可以使用new PropertyInConstructor().foo或访问的属性new PropertyWithGetSet().foo

我现在想要获取此类的现有属性(没有实例!)并尝试一下:

console.log(Object.getOwnPropertyNames(PropertyInConstructor.prototype));
console.log(Object.getOwnPropertyNames(PropertyWithGetSet.prototype));
Run Code Online (Sandbox Code Playgroud)

[“构造函数”]
[“构造函数”,“foo”]

为什么在构造函数中指定属性的调用没有添加“foo”属性?

是否缺少某些内容或有其他方式来获取这些属性?

Fen*_*ton 5

简短的回答:大多数属性都会在运行时动态添加到实例中。具有 getter 和 setter 的属性需要使用Object.defineProperty.

在运行时添加

用你的第一个例子:

export class PropertyInConstructor {
  constructor(public foo: boolean) {
  }
}
Run Code Online (Sandbox Code Playgroud)

该属性仅在构造函数运行时添加到实例中。这是转译后的 JavaScript:

var PropertyInConstructor = /** @class */ (function () {
    function PropertyInConstructor(foo) {
        this.foo = foo;
    }
    return PropertyInConstructor;
}());
Run Code Online (Sandbox Code Playgroud)

实际上,foo在构造函数运行之前,该属性并不存在于类中。

这不仅适用于构造函数属性,还适用于未针对原型定义的所有属性,例如:

class PropertyInConstructor {
    public foo: boolean;
    constructor() {
        this.foo = true;
  }
}
Run Code Online (Sandbox Code Playgroud)

定义属性

当您使用 get 和 set 时,情况有所不同,因为属性被添加到原型中:

var PropertyWithGetSet = /** @class */ (function () {
    function PropertyWithGetSet() {
        this._foo = false;
    }
    Object.defineProperty(PropertyWithGetSet.prototype, "foo", {
        get: function () {
            return this._foo;
        },
        set: function (theFoo) {
            this._foo = theFoo;
        },
        enumerable: true,
        configurable: true
    });
    return PropertyWithGetSet;
}());
Run Code Online (Sandbox Code Playgroud)