什么时候不需要“hasOwnProperty”?

When is `hasOwnProperty` not required?

什么时候不需要hasOwnProperty

这本书 JavaScript:好的部分 包括以下内容 "it is usually necessary":

The other form (called for in) enumerates the property names (or keys) of an object. On each iteration, another property name string from the object is assigned to the variable.

It is usually necessary to test object.hasOwnProperty(variable) to determine whether the property name is truly a member of the object or was found instead on the prototype chain.

for (myvar in obj) {
 if (obj.hasOwnProperty(myvar)) {
 ...
 }
}

更具体地说,我想枚举一个简单的类字典对象的属性,它是使用 Javasacript 对象文字语法创建的,例如:

var foo = { 'bar': 'baz' };

或使用 JSON.parse:

创建的类似对象
var foo = JSON.parse("{ 'bar': 'baz' }");

当我对 foo 对象执行 for in 时,我应该使用 hasOwnProperty 吗?

假设此 javascript 在随机浏览器中 运行 作为复杂网页的一部分。

是答案,"In practice it is probably/usually not necessary. In theory it could be necessary if some framework or library added a property by changing Object.prototype, but changing Object.prototype like that would be an intrusive bad practice which any respectable framework is unlikely to do"?

恕我直言,在现代 JS 解释器中,它几乎[*]从不需要,尤其是对于仅用作字典的普通对象。

jQuery 没有它也能很好地管理,因为人们已经知道不安全地将可枚举属性添加到 Object.prototype 是一个坏主意。

当然,

ES5 允许您将 不可枚举的 属性添加到 Object.prototype 中,如果您真的想要的话,使用 Object.defineProperty.

[*] 上述情况的例外情况是,如果您正在编写专门检查原型链的代码并且确实需要知道可枚举 属性 是否被继承

在 "sane, modernish, environment"[=24= 中迭代 普通对象 2 时不需要

hasOwnProperty ]1:这个假设意味着限制旧版浏览器支持。

所有标准 Object 属性在很长一段时间内都是不可枚举的,并且新的核心方法始终是不可枚举的。


1 如果代码决定添加到 Object.prototype,这除了 polyfills 之外还有很多问题,它应该将其添加为不可枚举的 属性 .添加新的可枚举 属性 违反了 "sane environment" 约束。 IE 9+(和 FF/Chrome/Safari 等)支持 Object.defineProperty 足以完成此任务。 IE 8 没有也违反了 "modernish" 约束。

2 数组不符合普通对象的条件。对于大多数数组迭代,也不建议使用 for..in

只有在绝对可预测的情况下才需要它,这意味着 - 几乎从不。

In ECMAScript 5.1, Object.create was added, which enables the creation of objects with a specified [[Prototype]]. Object.create(null) is a common pattern used to create objects that will be used as a Map. This can lead to errors when it is assumed that objects will have properties from Object.prototype. This rule prevents calling some Object.prototype methods directly from an object.

Additionally, objects can have properties that shadow the builtins on Object.prototype, potentially causing unintended behavior or denial-of-service security vulnerabilities. For example, it would be unsafe for a webserver to parse JSON input from a client and call hasOwnProperty directly on the resulting object, because a malicious client could send a JSON value like {"hasOwnProperty": 1} and cause the server to crash.

To avoid subtle bugs like this, it's better to always call these methods from Object.prototype. For example, foo.hasOwnProperty("bar") should be replaced with Object.prototype.hasOwnProperty.call(foo, "bar").