4

什么时候hasOwnProperty不需要?

这本书JavaScript: The Good Parts包括以下内容,即“通常是必要的”:

另一种形式(称为for in)枚举对象的属性名称(或键)。在每次迭代中,来自对象的另一个属性名称字符串被分配给 变量

通常需要测试对象hasOwnProperty(变量)来确定属性名称是真正的对象成员还是在原型链上找到的。

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

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

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

或使用以下方法创建的类似对象JSON.parse

var foo = JSON.parse("{ 'bar': 'baz' }");

我应该在对象上使用hasOwnProperty时使用吗?for infoo

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

答案是,“在实践中可能/通常没有必要。理论上,如果某些框架或库通过更改添加属性可能是必要的Object.prototype,但Object.prototype这样的更改将是一种侵入性的不良做法,任何受人尊敬的框架都不太可能这样做“?

4

3 回答 3

4

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

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

当然,ES5 允许你添加不可枚举的属性,Object.prototype如果你真的想的话,使用Object.defineProperty.

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

于 2017-01-09T00:06:57.280 回答
3

hasOwnProperty在“理智的、现代的、环境” 1中迭代普通对象2时不需要:这种假设意味着限制旧版浏览器支持。

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


1如果代码决定添加到Object.prototype,除了 polyfills 之外,这也是值得怀疑的,它应该将其添加为不可枚举的属性。添加新的可枚举属性违反了“健全的环境”约束。IE 9+(和 FF/Chrome/Safari 等)Object.defineProperty足以支持此任务。IE 8 没有也违反了“现代”约束。

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

于 2017-01-09T00:25:24.677 回答
0

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

在 ECMAScript 5.1Object.create中添加了,它允许创建具有指定[[Prototype]]. Object.create(null)是一种常见的模式,用于创建将用作 Map 的对象。当假定对象将具有来自 的属性时,这可能会导致错误Object.prototype。此规则防止 Object.prototype直接从对象调用某些方法。

此外,对象可能具有隐藏内置函数的属性 Object.prototype,可能会导致意外行为或拒绝服务安全漏洞。例如,Web 服务器解析来自客户端的 JSON 输入并 hasOwnProperty直接调用结果对象是不安全的,因为恶意客户端可能会发送类似的 JSON 值{"hasOwnProperty": 1}并导致服务器崩溃。

为避免此类细微错误,最好始终从Object.prototype. 例如,foo.hasOwnProperty("bar") 应替换为Object.prototype.hasOwnProperty.call(foo, "bar").

于 2020-04-30T18:31:39.983 回答