typescript - Javascript : Function equivalent of `for (let p in this)`

标签 typescript

正好好奇,for (let p in this)用的函数是什么?我正在重构代码并想替换

const result: string[] = [];
for (let p in this) { result.push(p); }

调用 const result = Object.getOwnPropertyNames(this);。但是因为我知道这个函数不返回继承的属性(就像外观一样)我需要找到一个不同的解决方案。我很确定有一个。

在我的场景中,基础模型(每个模型扩展的类)是this。我想获取具体类型实现的所有字段(和属性 [get/set])的数组。

编辑:我刚刚添加了 an example

最佳答案

你想重新实现这个:

function inheritedEnumerableKeys(x: object): string[] {
    const ret: string[] = [];
    for (let k in x) ret.push(k);
    return ret;
}

不使用 for...in loop .这是可能的,但这不是单线的。属于the different ways of traversing object properties in JavaScript ,只有 for...in 为您提供继承的属性键;其他一切都只给出自己的属性。所以如果你想获得继承的属性,你需要显式地 walk the prototype chain并从每个人那里收集自己的属性(property):

function inheritedEnumerableKeys(x: object): string[] {
    const proto = Object.getPrototypeOf(x);
    const ownKeys = Object.keys(x);
    return (proto && typeof proto === "object") ?
        [...ownKeys, ...inheritedEnumerableKeys(proto)] :
        ownKeys;
}

这是一个递归函数,但也可以将其写成一个循环,以便与 for...in 版本进行比较:

function inheritedEnumerableKeys(x: object): string[] {
    const ret: string[] = [];
    for (let v = x; v && typeof v === "object"; v = Object.getPrototypeOf(v)) {
        ret.push(...Object.keys(v));
    }
    return ret;
}

让我们测试一下。使用您的原始 modelProperties() 定义,我们得到以下输出:

console.log(new MyModel().modelProperties); 
// ["propertyA", "_propertyB", "propertyB"] 

如果我将实现更改为:

get modelProperties(): string[] {
    return inheritedEnumerableKeys(this);
}

我们得到相同的输出:

console.log(new MyModel().modelProperties); 
// ["propertyA", "_propertyB", "propertyB"] 

无论我们使用 inheritedEnumerableKeys() 的三个版本中的哪一个。

让我们针对具有显式原型(prototype)层次结构的对象测试这三个版本:

const z = { a: 1, b: 2, c: 3 };
const y = Object.assign(Object.create(z), { d: 4, e: 5, f: 6 });
const x = Object.assign(Object.create(y), { g: 7, h: 8, i: 9 });

inheritedEnumerableKeys() 的所有三个版本都产生

console.log(inheritedEnumerableKeys(x)); 
// ["g", "h", "i", "d", "e", "f", "a", "b", "c"] 

那么,这就是您所提问题的答案。

但是在没有一些相反的强大用例的情况下,我建议直接使用 for...in 循环,它比任何一个都更简单、更惯用,而且很可能更高效其他方法。

Playground link to code

关于typescript - Javascript : Function equivalent of `for (let p in this)` ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73879069/

相关文章:

typescript - 如何使用 typescript 转译,只有特定文件?

typescript - 如何在 typescript 中正确使用lodash-es?

angularjs - 我应该如何在 Typescript 中定义 promise 回调的类型?

javascript - 消费者和 vendor 的 LTI 合规示例

javascript - Angular 8 NgRx - 错误 : Detected unserializable action

typescript - 如何声明实现多个接口(interface)的 typescript 属性

angular - 从使用命名空间的外部 typescript 库导入类

javascript - TypeScript - 结合两个接口(interface)并使其某些成员成为强制性的

javascript - Typescript:根据条件过滤联合

javascript - [tslint]预期一个 'for-of' 循环而不是一个 'for' 循环与这个简单的迭代(prefer-for-of)