简体   繁体   English

在JavaScript中检查没有hasOwnProperty的哈希键的存在

[英]Checking existence of hash key without hasOwnProperty in JavaScript

Given this example data: 给定此示例数据:

let foo = [1,2,2,3,5,3]
let seen = {}

What is the difference between the following ways to check the existence of a key? 以下几种检查密钥是否存在的方式有什么区别? Can I run into some hiccups using the first way? 我可以使用第一种方法遇到麻烦吗?

foo.filter(function(item) {
    return seen[item] ? false : (seen[item] = true);
});

vs.

foo.filter(function(item) {
    return seen.hasOwnProperty(item) ? false : (seen[item] = true);
});

First off, as shown in the question, both are incorrect because you're not using the return value of filter (a new, filtered array). 首先,如问题所示,两者都不正确,因为您没有使用filter (新的,经过过滤的数组)的返回值。 Use forEach or (on modern systems) for-of in that case. 在这种情况下,应使用forEach或(在现代系统上) for-of But perhaps you actually are using it and just didn't show that in your question. 但是也许您实际上正在使用它,只是在您的问题中没有显示出来。

Addressing your main question: 解决您的主要问题:

The first way will incorrectly assume something wasn't seen if it's falsy . 第一种方法会错误地假设某些东西是虚假的,则不会被看到。 The falsy values are 0 , "" , NaN , null , undefined , and of course false . 伪造的值为0""NaNnullundefined ,当然还有false (All other values are truthy .) Your second way will handle those correctly. (所有其他值都是正确的 。)第二种方法将正确处理这些值。

Another difference between your two checks is that the first gets the property regardless of where it is in the prototype chain; 两次检查之间的另一个区别是,无论对象在原型链中的哪个位置,第一个都会获取该属性; the second only looks at the object itself (which is probably what you want). 第二个仅查看对象本身(这可能是您想要的)。 For your example object, this really only matters for properties provided by Object.prototype such as valueOf , but... 对于您的示例对象,这实际上仅对Object.prototype提供的属性(例如valueOf Object.prototype ,但是...

You might also look into Set or Map . 您可能还会查看SetMap

Short answer : there are no problems in this case for not using Object.hasOwnProperty() [wiki] 简短的答案 :在这种情况下,不使用Object.hasOwnProperty()不会有问题[wiki]

When would it be a problem? 什么时候会出问题?

 let seen = {} console.log(seen["constructor"]) // function Object() { [native code] } 

as you can see this will also hold other strings for inherited properties like constructor of an Object. 如您所见,这还将包含继承属性的其他字符串,例如Object的constructor Since you are only dealing with numbers there a no such properties on Object. 由于您只处理数字,因此对象上没有此类属性。

In addition to what TJ said. 除了TJ所说的。

hasOwnProperty will not search the prototype of the object while the bracket or dot notation will. hasOwnProperty将不搜索对象的原型,而将使用方括号或点表示法。 See this example 看这个例子

 Object.prototype.foo = 1; var baz = {"bar": 1} if (baz.hasOwnProperty('foo')) { console.log('has foo'); return true } if (baz.bar) { console.log('has bar'); // has bar return true; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM