【问题标题】:Get properties of class in typescript在打字稿中获取类的属性
【发布时间】:2017-01-31 14:02:04
【问题描述】:

我有以下课程:

export class Test {

        private _rowsCount: string;
        public get RowsCount(): string {
            return this._rowsCount;
        };
        public set RowsCount(value: string) {
            this._rowsCount = value;
        };

        private _rowsCount2: string;
        public get RowsCount2(): string {
            return this._rowsCount2;
        };
        public set RowsCount2(value: string) {
            this._rowsCount2 = value;
        };
    }

我需要遍历特定类中的属性,我尝试了以下方法:

Object.keys(this).forEach((key)=> {
    console.log(key);
});

但是这个迭代只是在private 字段上的问题,我还尝试了以下我得到了所有methodsproperties

    for (var property in this) {
        if (this.hasOwnProperty(property)) {
            console.log(property);                
        }
    }

有人有解决办法吗?

谢谢!

【问题讨论】:

  • for/in 循环给了你所有这些,这不是你想要的吗?你想得到什么?
  • for/in 还提供了方法和构造函数(如果存在)!我不想要这些,我只需要公共属性!
  • “属性”是指仅获取器/设置器吗?还是会员?您需要更准确地说明您要问的内容,因为它根本不清楚。
  • 我只需要获取 getter/setter。

标签: javascript typescript


【解决方案1】:

如果您只需要获取 getter/setter,那么您需要执行以下操作:

class Test {
    ...

    public static getGetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["get"] === "function"
        });
    }

    public static getSetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["set"] === "function"
        });
    }
}

Test.getGetters(); // ["RowsCount", "RowsCount2"]
Test.getSetters(); // ["RowsCount", "RowsCount2"]

(code in playground)


您可以将静态方法放在基类中,然后当您扩展它时,子类也将具有这些静态方法:

class Base {
    public static getGetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["get"] === "function"
        });
    }

    public static getSetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["set"] === "function"
        });
    }
}

class Test extends Base {
   ...
}

Test.getGetters(); // work the same

(code in playground)

如果您希望这些方法成为实例方法,那么您可以这样做:

class Base {
    public getGetters(): string[] {
        return Object.keys(this.constructor.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.constructor.prototype, name)["get"] === "function"
        });
    }

    public getSetters(): string[] {
        return Object.keys(this.constructor.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.constructor.prototype, name)["set"] === "function"
        });
    }
}

变化在于,您使用的是this.constructor.prototype,而不是this.prototype
那么你只需:

let a = new Test();
a.getGetters(); // ["RowsCount", "RowsCount2"]

(code in playground)


编辑

基于@Twois 的评论,他指出在以 es6 为目标时它不起作用,这是一个可以工作的版本:

class Base {
    public static getGetters(): string[] {
        return Reflect.ownKeys(this.prototype).filter(name => {
            return typeof Reflect.getOwnPropertyDescriptor(this.prototype, name)["get"] === "function";
        }) as string[];
    }

    public static getSetters(): string[] {
        return Reflect.ownKeys(this.prototype).filter(name => {
            return typeof Reflect.getOwnPropertyDescriptor(this.prototype, name)["set"] === "function";
        }) as string[];
    }
}

主要区别:使用Reflect.ownKeys(this.prototype) 而不是Object.keys(this.prototype)

【讨论】:

  • 好!,有没有办法做一个具有这些方法的 RootTest 并且每个嵌套类都可以调用它们来获取他自己的 getter/setter?我注意到,如果我将方法的定义更改为非静态将找不到原型
  • 如果目标是 es6 或更高版本,这将不再起作用,因为 TS 现在使用本机 js getter 和 setter。
  • 我们可以使用Keyof 吗?
【解决方案2】:

你可以做的就是为你想要使用的类扩展上面的类,并为此公开属性;

   class TestExposed extend Test {
      public _rowsCount: string;
      public _rowsCount2: string; 
   }

并在您的 Test 类中进行私有保护:

class Test {
    protected _rowsCount: string;
    public get RowsCount(): string {
        return this._rowsCount;
    };
    public set RowsCount(value: string) {
        this._rowsCount = value;
    };

    protected _rowsCount2: string;
    public get RowsCount2(): string {
        return this._rowsCount2;
    };
    public set RowsCount2(value: string) {
        this._rowsCount2 = value;
    };
}

那么您应该能够迭代外部类中的属性;

但如果你想拥有价值观;为什么不创建一个函数,通过在数组中返回值或将它们记录为字符串来公开值;

【讨论】:

    猜你喜欢
    • 2019-08-11
    • 2021-12-06
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2021-12-04
    • 2018-06-05
    • 2018-01-18
    • 1970-01-01
    相关资源
    最近更新 更多