0

我遇到了 JavaScript 中属性反射的一小段代码:

function GetProperties(obj) {
    var result = [];
    for (var prop in obj) {
        if (typeof obj[prop] !== "function") {
            result.push(prop);
        }
    }
    return result;
}

我已经使用以下“CustomObject”对其进行了测试:

var CustomObject = (function () {
    function CustomObject() {
        this.message = "Hello World";
        this.id = 1234;
    }

    Object.defineProperty(CustomObject.prototype, "Foo", {
        get: function () {
            return "foo";
        },
        enumerable: true,
        configurable: true
    });

    Object.defineProperty(CustomObject.prototype, "Bar", {
        get: function () {
            return "bar";
        },
        enumerable: true,
        configurable: true
    });

    return CustomObject;
})();

这是一个使用 jQuery 的小测试:

$(document).ready(function () {
    console.log(GetProperties(new CustomObject()));
});

结果如下:

["message", "id", "Foo", "Bar"]

我知道 GetProperties 函数只返回输入对象中不是函数的任何内容的数组,但我想过滤结果以仅获取“真实”属性,所以我的输出应该是:

["Foo", "Bar"]

这可能吗?

另外,我可以做相反的事情并返回字段吗?

4

2 回答 2

1

您可以做两件事(可能更多,这取决于您的具体情况):

  1. 以不同的方式命名“私有”属性,例如使用尾随下划线并在您迭代属性(并排除它们)时检查属性名称是否以下划线结尾。

  2. 如果“真实属性”是指原型上定义的属性,并且您想忽略对象本身上定义的所有属性,则可以使用.hasOwnPrototype它来检查它的定义位置。或者,您可以Object.getPrototypeOf仅使用和迭代原型的属性。

于 2013-05-17T16:37:41.293 回答
0

错误的代码。我要离开(带评论),因为随后的讨论可能会帮助其他人。

如果您总是使用 defineProperty() 来获取不可枚举的属性,那么这将起作用:

function GetProperties(obj) {
    var result = [];
    for (var prop in obj) {
        // propertyIsEnumerable() returns false just because the properties
        // are inherited thru the prototype chain. It was just a coincidence
        // that it got the desired result. Don't do this.
        if (typeof obj[prop] !== "function" && !obj.propertyIsEnumerable(prop)) {
            result.push(prop);
        }
    }
    return result;
}

否则,我很想知道该问题的一般解决方案。

编辑:我看到代码已经enumerable: true并且我的代码仍然完全按照要求执行。加倍你发球?

于 2013-05-17T16:41:30.170 回答