JavaScript属性&;场反射

JavaScript属性&;场反射,javascript,object,reflection,properties,field,Javascript,Object,Reflection,Properties,Field,我在JavaScript中遇到了一段用于属性反射的代码: function GetProperties(obj) { var result = []; for (var prop in obj) { if (typeof obj[prop] !== "function") { result.push(prop); } } return result; } 我使用以下“CustomObject”对其进行了测试

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

function GetProperties(obj) {
    var result = [];
    for (var prop in obj) {
        if (typeof obj[prop] !== "function") {
            result.push(prop);
        }
    }
    return result;
}
我使用以下“CustomObject”对其进行了测试:

下面是一个使用jQuery的小测试:

$(document).ready(function () {
    console.log(GetProperties(new CustomObject()));
});
结果如下:

["message", "id", "Foo", "Bar"]
我知道GetProperties函数只返回输入对象中不是函数的任何内容的数组,但我希望过滤结果以仅获取“真实”属性,因此我的输出应该是:

["Foo", "Bar"]
这可能吗


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

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

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

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

  • 错误代码。我(带着评论)离开,因为接下来的讨论 可能会帮助别人

    如果始终使用defineProperty()获取不可枚举的属性,则这将起作用:

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


    EDIT:我看到代码具有
    可枚举性:true
    ,但我的代码仍然完全按照要求执行。加倍你的tee ef?

    没有理由使用
    !循环中的对象属性可枚举(prop)
    。如果该属性不可枚举,则仍将跳过该属性。然后是双WTF?等等,我正在用shell运行代码。我会在本地试试看是否能得到同样的结果。编辑:在本地尝试,结果相同。是的,这很奇怪
    obj.propertyEnumerable(prop)
    正在为未通过
    defineProperty
    添加的属性返回
    false
    。。。他们显然被列举出来了。FF和Chrome中的行为相同。对于一个名为
    propertyEnumerable
    Ah的方法来说,这是一个奇怪的行为,我明白了。我把它倒过来了。它说原型链上的那些是不可枚举的。通过规范检查,
    propertyEnumerable
    不会查看原型属性。“注意1,这个方法不考虑原型链中的对象。”JavaScript恢复了信念,然后…在问了另一个问题()之后,我理解了在对象或原型上实现属性的区别。在此之前,我的理解是,在原型上实现的任何东西都会成为构建原型的任何东西的实例成员。我现在可以看出区别了。
    ["Foo", "Bar"]
    
    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;
    }