我看到了这段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"]
这可能吗?
另外,我可以做相反的事情,只返回字段吗?
您可以做两件事(可能更多,这取决于您的具体情况):
-
以不同的方式命名"private"属性,例如,在属性上迭代(并排除它们)时,检查属性名称是否以下划线结束。
-
如果你所说的"真实属性"是指在原型上定义的属性,并且你想忽略对象本身定义的所有属性,你可以使用
.hasOwnPrototype
来检查它的定义位置。或者,您可以使用Object.getPrototypeOf
并只迭代原型的属性。
错误代码。因为接下来的讨论,我要离开了也许能帮到别人。
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;
}
否则,我很想知道这个问题的一般解决办法。
EDIT:我看到代码有enumerable: true
,我的代码仍然完全按照要求做。你的发球加倍了吗?