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

时间:2017-12-06 10:52:06

标签: typescript reflection

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

想象一下以下几个类:

export class PropertyInConstructor {

  constructor(public foo: boolean) {

  }
}
export class PropertyWithGetSet {

  private _foo: boolean = false;

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

  set foo(theFoo: boolean) {
    this._foo = theFoo;
  }
}

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

我现在想获得这样一个类的现有属性(没有实例!)并尝试一下:

console.log(Object.getOwnPropertyNames(PropertyInConstructor.prototype));
console.log(Object.getOwnPropertyNames(PropertyWithGetSet.prototype));
  

[ “构造”]
  [“constructor”,“foo”]

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

是否有遗漏或其他方式获得这些属性?

1 个答案:

答案 0 :(得分:2)

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

在运行时添加

用你的第一个例子:

export class PropertyInConstructor {
  constructor(public foo: boolean) {
  }
}

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

var PropertyInConstructor = /** @class */ (function () {
    function PropertyInConstructor(foo) {
        this.foo = foo;
    }
    return PropertyInConstructor;
}());

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

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

class PropertyInConstructor {
    public foo: boolean;
    constructor() {
        this.foo = true;
  }
}

定义属性

使用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;
}());