关于数组:检查javascript对象中是否存在键?

Checking if a key exists in a JavaScript object?

如何检查javascript对象或数组中是否存在特定的键?

如果一个密钥不存在,并且我试图访问它,它会返回false吗?或者抛出一个错误?


检查未定义不是测试密钥是否存在的准确方法。如果键存在但值实际上是undefined,该怎么办?

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

您应该使用in操作符:

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

如果要检查键是否不存在,请记住使用括号:

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

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

1
obj.hasOwnProperty("key") // true

对于inhasOwnProperty和key为undefined的方法的性能比较,见本基准。


快速回答

How do I check if a particular key exists in a JavaScript object or array?
If a key doesn't exist and I try to access it, will it return false? Or throw an error?

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

运算速度慢、可靠性高、无属性方法

正如人们在这里已经提到的,您可以拥有一个具有与"未定义"常量关联的属性的对象。

1
 var bizzareObj = {valid_key:  undefined};

在这种情况下,您必须使用hasownproperty或in operator来知道密钥是否真的存在。但是,以什么价格呢?

所以,我告诉你…

在运算符和HasObjor属性中,"方法"使用JavaScript中的属性描述符机制(类似Java语言中的Java反射)。

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

The Property Descriptor type is used to explain the manipulation and reification of named property attributes. Values of the Property Descriptor type are records composed of named fields where each field’s name is an attribute name and its value is a corresponding attribute value as specified in 8.6.1. In addition, any field may be present or absent.

另一方面,调用对象方法或键将使用javascript[[get]]机制。那要快得多!

基准

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

Comparing key access in JS

在运算符中使用

1
var result ="Impression" in array;

结果是

1
12,931,832 ±0.21% ops/sec      92% slower

使用HasOwnProperty

1
var result = array.hasOwnProperty("Impression")

结果是

1
16,021,758 ±0.45% ops/sec     91% slower

直接访问元素(括号样式)

1
var result = array["Impression"] === undefined

结果是

1
168,270,439 ±0.13 ops/sec     0.02% slower

直接访问元素(对象样式)

1
var result = array.Impression  === undefined;

结果是

1
168,303,172 ±0.20%     fastest

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

那个问题使我困惑。在javascript中,至少有两个对缺少的对象的引用,以避免这样的问题:nullundefined

null是原始值,表示有意不存在任何对象值,或者简而言之,是确定的缺乏值。另一方面,undefined是未知值(未定义)。如果有一个属性将在以后使用合适的值,考虑使用null引用而不是undefined,因为在最初的时刻,该属性被确认为缺少值。

比较:

1
2
3
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()方法。

编辑:2018年4月12日-不再相关

正如人们所评论的,现代版本的javascript引擎(除了火狐)已经改变了访问属性的方法。对于这个特定的情况,当前的实现比前一个慢,但是访问键和对象之间的差异是可以忽略的。


它将返回undefined

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

undefined是一个特殊的常数值。所以你可以说,例如

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

这可能是检查丢失钥匙的最佳方法。但是,正如下面的注释所指出的,理论上您可能希望实际值为undefined。我从来没有必要这么做,也不知道我为什么要这么做的原因,但是为了完整起见,你可以使用in操作符。

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


接受的回答是指反对。小心使用数组上的in运算符查找数据而不是键:

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

测试数组中的现有元素:查找项目是否在javascript数组中的最佳方法?


1
"key" in obj

可能只测试与数组键非常不同的对象属性值


检查javascript对象中是否存在属性的三种方法:

  • !!对象属性将值转换为bool。对于除"false"值之外的所有值返回true
  • obj中的"属性"如果属性存在,则返回true,无论其值是多少(甚至为空)
  • 对象属性("属性")。不检查原型链。(由于所有对象都有"ToString"方法,1和2将在其上返回true,而3可以在其上返回false。)
  • 参考文献:

    http://book.mixu.net/node/ch5.html


    如果您使用的是underline.js库,那么对象/数组操作将变得简单。

    在您的情况下,可以使用has方法。例子:

    1
    2
    3
    yourArray = {age:"10"}

    _.has(yourArray,"age")

    返回真

    但是,

    1
    _.has(yourArray,"invalidKey")

    返回错误


    答:

    1
    2
    3
    4
    5
    6
    7
    8
    if ("key" in myObj)
    {
        console.log("key exists!");
    }
    else
    {
        console.log("key doesn't exist!");
    }

    说明:

    in运算符将检查对象中是否存在密钥。如果检查值是否未定义:if (myObj["key"] === 'undefined'),则可能会遇到问题,因为使用undefined值的对象中可能存在密钥。

    因此,最好先使用in运算符,然后在知道它存在后比较键内的值。


    这里有一个助手函数,我觉得非常有用

    keyExists(key, search)可用于轻松查找对象或数组中的键!

    只要把你想找到的键传给它,然后搜索你想找到的对象(对象或数组)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function keyExists(key, search) {
        if (!search || (search.constructor !== Array && search.constructor !== Object)) {
            return false;
        }
        for (var i = 0; i < search.length; i++) {
            if (search[i] === key) {
                return true;
            }
        }
        return key in search;
    }

    如何使用它:搜索数组中的键

    1
    2
    keyExists('apple', ['apple', 'banana', 'orange']); // true
    keyExists('fruit', ['apple', 'banana', 'orange']); // false

    在对象中搜索键

    1
    2
    keyExists('age', {'name': 'Bill', 'age': 29 }); // true
    keyExists('title', {'name': 'Jason', 'age': 29 }); // false

    它非常可靠,跨浏览器运行良好。


    瓦尼拉JS

    1
    yourObjName.hasOwnProperty(key) : true ? false;

    如果要检查ES2015中对象是否至少有一个属性

    1
    Object.keys(yourObjName).length : true ? false

    ES6溶液

    使用Array#someObject.keys。如果给定的键存在于对象中,则返回"真";否则返回"假"。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var obj = {foo: 'one', bar: 'two'};
       
    function isKeyInObject(obj, key) {
        var res = Object.keys(obj).some(v => v == key);
        console.log(res);
    }

    isKeyInObject(obj, 'foo');
    isKeyInObject(obj, 'something');

    一行示例。

    1
    console.log(Object.keys({foo: 'one', bar: 'two'}).some(v => v == 'foo'));


    我们可以用-hasOwnProperty.call(obj, key);

    underline.js方式-

    1
    2
    3
    4
    5
    6
    7
    if(_.has(this.options, 'login')){
      //key 'login' exists in this.options
    }

    _.has = function(obj, key) {
      return hasOwnProperty.call(obj, key);
    };

    最简单的检查方法是

    1
    "key" in object

    例如:

    1
    2
    3
    4
    5
    6
    var obj = {
      a: 1,
      b: 2,
    }
    "a" in obj // true
    "c" in obj // false

    返回值为true表示该对象中存在键。


    对于那些在他们的项目中包含了lodash:有一个lodash-get方法试图获得"深"键:

    Gets the value at path of object. If the resolved value is undefined,
    the defaultValue is returned in its place.

    1
    2
    3
    4
    5
    6
    7
    8
    var object = { 'a': [{ 'b': { 'c': 3 } }] };

    console.log(
      _.get(object, 'a[0].b.c'),           // => 3
      _.get(object, ['a', '0', 'b', 'c']), // => 3
      _.get(object, 'a.b.c'),              // => undefined
      _.get(object, 'a.b.c', 'default')    // => 'default'
    )
    1
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js">

    这将有效地检查是否定义了该键(无论其深度如何),并且不会引发错误,如果未定义该键,则可能会损害程序流。


    yourarray.indexof(yourarrayName)>-1

    1
    2
    3
    fruit = ['apple', 'grapes', 'banana']

    fruit.indexOf('apple') > -1

    1
    2
    3
    fruit = ['apple', 'grapes', 'banana']

    fruit.indexOf('apple1') > -1


    虽然这必须检查键是否存在,但它确实检查值的真实性。这是undefinednull所属的。

    Boolean(obj.foo)

    这个解决方案最适合我,因为我使用了typescript,并且使用了像这样的字符串'foo' in objobj.hasOwnProperty('foo')。检查键是否存在不提供IntelliSense。


    这些例子可以证明不同方法之间的差异。希望它能帮助您根据自己的需要选择合适的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // Lets create object `a` using create function `A`
    function A(){};
    A.prototype.onProtDef=2;
    A.prototype.onProtUndef=undefined;
    var a=new A();
    a.ownProp = 3;
    a.ownPropUndef = undefined;

    // Let's try different methods:

    a.onProtDef; // 2
    a.onProtUndef; // undefined
    a.ownProp; // 3
    a.ownPropUndef; // undefined
    a.whatEver; // undefined
    a.valueOf; // ? valueOf() { [native code] }

    a.hasOwnProperty('onProtDef'); // false
    a.hasOwnProperty('onProtUndef'); // false
    a.hasOwnProperty('ownProp'); // true
    a.hasOwnProperty('ownPropUndef'); // true
    a.hasOwnProperty('whatEver'); // false
    a.hasOwnProperty('valueOf'); // false

    'onProtDef' in a; // true
    'onProtUndef' in a; // true
    'ownProp' in a; // true
    'ownPropUndef' in a; // true
    'whatEver' in a; // false
    'valueOf' in a; // true (on the prototype chain - Object.valueOf)

    Object.keys(a); // ["ownProp","ownPropUndef"]

    如果要在对象的任何深度检查任何键并考虑错误值,请考虑实用程序函数的这一行:

    1
    var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;

    结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    var obj = {
        test:"",
        locals: {
            test:"",
            test2: false,
            test3: NaN,
            test4: 0,
            test5: undefined,
            auth: {
                user:"hw"
            }
        }
    }

    keyExistsOn(obj,"")
    > false
    keyExistsOn(obj,"locals.test")
    > true
    keyExistsOn(obj,"locals.test2")
    > true
    keyExistsOn(obj,"locals.test3")
    > true
    keyExistsOn(obj,"locals.test4")
    > true
    keyExistsOn(obj,"locals.test5")
    > true
    keyExistsOn(obj,"sdsdf")
    false
    keyExistsOn(obj,"sdsdf.rtsd")
    false
    keyExistsOn(obj,"sdsdf.234d")
    false
    keyExistsOn(obj,"2134.sdsdf.234d")
    false
    keyExistsOn(obj,"locals")
    true
    keyExistsOn(obj,"locals.")
    false
    keyExistsOn(obj,"locals.auth")
    true
    keyExistsOn(obj,"locals.autht")
    false
    keyExistsOn(obj,"locals.auth.")
    false
    keyExistsOn(obj,"locals.auth.user")
    true
    keyExistsOn(obj,"locals.auth.userr")
    false
    keyExistsOn(obj,"locals.auth.user.")
    false
    keyExistsOn(obj,"locals.auth.user")
    true

    另请参阅此NPM包:https://www.npmjs.com/package/has-deep-value


    带javascript破坏功能的新的令人敬畏的解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    let obj = {
       "key1":"value1",
       "key2":"value2",
       "key3":"value3",
    };

    let {key1, key2, key3, key4} = obj;

    // key1 ="value1"
    // key2 ="value2"
    // key3 ="value3"
    // key4 = undefined

    // Can easily use `if` here on key4
    if(!key4) { console.log("key not present"); } // Key not present

    检查javascript销毁的其他用途