如何检查一个 JavaScript 对象或数组中是否存在某个特定键?

如果键不存在,并且我尝试访问它,将它返回 false。或引发错误?

2009-07-08 13:21:32
问题评论:

中的所有内容 (几乎所有) JavaScript 对象或可强制转换为一个。这是伪关联数组生来就像 @PatrickM 指出的那样。

回答:

检查未定义的状态不能准确地测试某个键是否存在。如果此项存在但值未实际undefined?

var obj = { key: undefined };
obj["key"] != undefined // false, but the key exists!

您应改用in运算符︰

"key" in obj // true, regardless of the actual value

如果您想要检查如果键不存在,请记住使用括号︰

!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj   // ERROR!  Equivalent to "false in obj"

或者,如果要特别测试的对象实例的属性 (并不继承的属性) 时,使用hasOwnProperty:

obj.hasOwnProperty("key") // true

绝对的没有意义时遇到具有未定义使手动定义值的属性。它真的会自相矛盾。

我意识到有情况下故意让属性设置为未定义的使用。

有效使用案例︰ Gecko 1.9.1 [Firefox 3.5] 有没有 window.onhashchange 属性。Gecko 1.9.2 [Firefox 3.6] 有此属性设置为未定义 (直到希更改)。对功能检测的哈希的历史记录或浏览器版本,其中一个必须使用 window.hasOwnProperty("onhashchange");

PHP 中存在类似的问题在空 = = 不存在︰ stackoverflow.com/q/418066/372654和遗憾的是,空使用有出现过。

@joebert 只是一些毫无意义,并不意味着不会在生产代码中遇到它。有多个库的无意义的事情。

快速回答

如何检查一个 JavaScript 对象或数组中是否存在某个特定键?如果键不存在,我尝试访问它,将它返回 false。或引发错误?

直接访问缺少使用样式 (关联) 数组或对象样式属性,则将返回未定义的常数。

速度慢而且可靠运算符和hasOwnProperty方法

因为人们已经在此处介绍,可能具有一个属性,该属性与"未定义"的常数中没有该对象。

 var bizzareObj = {valid_key:  undefined};

在这种情况下,必须使用hasOwnProperty运算符来知道密钥是否真的存在。但是, ,但以什么价格?

因此,我将告诉您...

in运算符和hasOwnProperty都是用 Javascript (类似于 Java 反射中的 Java 语言) 的属性描述符机制的"方法"。

http://www.ecma-international.org/ecma-262/5.1/#sec-8.10

属性描述符类型用于解释操作和 reification 的命名的属性的特性。属性描述符类型的值是记录由其中每个字段的名称是属性名称,它的值是相应的属性值中指定的 8.6.1 作为命名字段组成。此外,任何字段可能存在或不存在。

相反,调用对象方法或键会使用 Javascript [获得] 机制。这就是得这样快 !

准则

http://jsperf.com/checking-if-a-key-exists-in-a-javascript-array

Comparing key access in JS.

使用in运算符
var result = "Impression" in array;

结果是

12,931,832 ±0.21% ops/sec      92% slower 
使用 hasOwnProperty
var result = array.hasOwnProperty("Impression")

结果是

16,021,758 ±0.45% ops/sec     91% slower
直接访问元素 (括号样式)
var result = array["Impression"] === undefined

结果是

168,270,439 ±0.13 ops/sec     0.02% slower 
直接访问元素 (对象样式)
var result = array.Impression  === undefined;

结果是

168,303,172 ±0.20%     fastest

编辑︰ 将undefined的值分配给属性的原因是什么?

这个问题 puzzles 我。在 Javascript 中,有没有对象以避免此类问题至少两个引用︰nullundefined.

null是值的表示有意没有任何对象,或在短条款,确认缺乏值的基元值。另一方面,undefined是未知的值 (未定义)。适当的值以后使用一个属性是否考虑使用null引用,而不是undefined,因为在初始时刻的属性是确认缺少值。

比较︰

var a = {1: null}; 
console.log(a[1] === undefined); // output: false. I know the value at position 1 of a[] is absent and this was by design, i.e.:  the value is defined. 
console.log(a[0] === undefined); // output: true. I cannot say anything about a[0] value. In this case, the key 0 was not in a[].

最终建议

避免使用undefined的值的对象。只要可能,就直接检查和使用null来初始化属性值。否则,使用较慢in运算符或hasOwnProperty()方法。

所有这些方法是在所有常用浏览器,如 IE8 + 可以接受吗?

@Justin 是。它应起的作用。您可以直接在jsperf.com/checking-if-a-key-exists-in-a-javascript-array上进行测试.

用于基准测试的 + 1。谢谢,这是我所希望查找的信息。明确一个强参数,来编写代码,永远不会指派或需要一个密钥,用于包含值未定义.

我是好奇如何 Underscore.js 的 has() 进行比较,因此我将它添加到 jsperf (版本 11)。变的出很慢组一起在 hasOwnProperty() 中。

惊人的对另一种方法使用基准测试。!!!哇...+ 1

它将返回undefined.

var aa = {hello: "world"};
alert( aa["hello"] );      // popup box with "world"
alert( aa["goodbye"] );    // popup box with "undefined"

undefined为特殊的常数值。因此可以说例如

// note the three equal signs so that null won't be equal to undefined
if( aa["goodbye"] === undefined ) {
    // do something
}

这可能是最好的方法,以检查有缺少的项。但是,是在下面的评论中指出,就理论上可能要有实际值是undefined的。我已经永远不需要这样做,为什么我将以往任何时候都想,但只是为了完整起见,您可以使用in运算符不能 offhand 的原因思考

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}

如果键存在,但实际上未定义的值,是吗?

您应该使用 === 而不是 = = 时比较于未定义,否则空将比较结果相等于未定义。

黎国明您的答案并不完全准确。因为无论如何 (和当然不以往任何时候都应) 未定义不是一个特殊常量值。事实上,它不是保留的关键字,可以覆盖它,让我们说,var undefined = 42;当您测试未定义的属性,应始终使用((typeof variable) === "undefined").

@ssiceundefined不是可写属性根据规格ecma-international.org/ecma-262/5.1/#sec-15.1.1.3

在早期版本的 JavaScript,未定义和 NaN 是可变变量,可以重新定义或赋了其他值这是一件坏事情。已修复 ECMAScript 5 中。

"key" in obj

可能测试仅对象属性值的数组键很大的不同

接受答案指的对象请注意在数组上使用in运算符查找数据而不是密钥︰

("true" in ["true", "false"])
// -> false (Because the keys of the above Array are actually 0 and 1)

若要测试现有元素数组中︰ JavaScript 数组中是否有某一项的最佳方式?

请输入您的翻译

Checking if a key exists in a JavaScript object?

确认取消