建议始终使用hasOwnProperty,但在许多情况下不需要这样做。 例如,请考虑以下代码:
var object = JSON.parse(somejsontext);
for(var prop in object) {
console.log(object[prop]);
}
我知道在这种情况下prop
是对象的一部分,它由for..in
明确定义。
但是根据MOZ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty,我们应该使用它来避免迭代不可信的道具,这个例子:
var buz = {
fog: 'stack'
};
for (var name in buz) {
if (buz.hasOwnProperty(name)) {
console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]);
}
else {
console.log(name); // toString or something else
}
}
但实际上测试这段代码,永远不会去其他地方。
那么什么时候才能使用hasOwnProperty
?
更新:考虑到选择的答案,我们可以安全地避免在这种情况下使用hasOwnProperty:
- Object
js尚未被任何JavaScript库或我们的代码扩展
- Object
是一个我们可以控制的简单代码
答案 0 :(得分:7)
当 prototype 包含您的代码未预料到的可枚举属性时,会出现问题。例如,假设这在您的示例之前运行:
Object.prototype.foobar = "hello";
在这种情况下,迭代buz
将包括可枚举的foobar
原型属性。这种hasOwnProperty
模式允许您的代码区分对象上直接的属性,以及从原型祖先继承的属性。
问题不是"枚举非可枚举的属性" (根据定义,这是不可能的,除非你为原型层次结构的每个级别通过getOwnPropertyNames
明确地获取它们),而是枚举继承的属性。当使用可以向高级原型添加可枚举属性的库时,这是一个问题,正如我在上面所说明的那样。
如果要在不导致枚举该属性的情况下向原型添加属性,可以使用Object.defineProperty
创建一个不可枚举的属性:
Object.defineProperty(Object.prototype, "foobar", {
value: "hello",
enumerable: false,
writeable: true,
configurable: true
});
这样的属性 not 会出现在for..in
上的buz
循环中(或直接在for..in
上的Object.prototype
循环中)