提问



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


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

最佳参考


检查undefined-ness不是测试密钥是否存在的准确方法。如果密钥存在但值实际上是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


对于inhasOwnProperty和关键是undefined的方法之间的性能比较,请参见基准 [71]

其它参考1


快速回答




  如何检查JavaScript对象或数组中是否存在特定键?
  如果密钥不存在而我尝试访问它,它会返回false吗?或者抛出错误?



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


运算符中缓慢可靠的和 hasOwnProperty 方法



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


 var bizzareObj = {valid_key:  undefined};


在这种情况下,您必须在运算符中使用 hasOwnProperty 或来了解密钥是否真的存在。但是,但价格是多少?


所以,我告诉你......


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


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



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



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


基准



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





在运算符中使用

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值分配属性的原因是什么?



那个问题困扰着我。在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()方法。


编辑:12/04/2018 - 不相关任何人



正如人们所评论的那样,现代版本的Javascript引擎(使用firefox异常)改变了访问属性的方法。对于这种特定情况,当前实现比前一个实现慢,但是访问密钥和对象之间的差异是可忽略的。

其它参考2


它将返回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运算符


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

其它参考3


接受的答案是指对象。注意使用Array上的in运算符来查找数据而不是键: [75] [76] [77]


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


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

其它参考4


"key" in obj


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

其它参考5


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



  1. !! obj.theProperty 结果
    将值转换为bool。除false值之外的所有值都返回TRUE

  2. obj中的属性

    如果属性存在,则返回true,无论其值(甚至为空)

  3. obj.hasOwnProperty( 利人)结果
    不检查原型链。 (因为所有对象都有toString方法,1和2将返回true,而3可以返回false。)



参考:



  http://book.mixu.net/node/ch5.html[79]


其它参考6


如果您使用underscore.js库,则对象/数组操作变得简单。 [80]


在你的情况下,可以使用_.has方法。例:


yourArray = {age: "10"}

_.has(yourArray, "age")


返回 true


但,


_.has(yourArray, "invalidKey")


返回 false

其它参考7


这是一个我觉得非常有用的辅助函数



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


只需将要查找的密钥传递给它,然后搜索要在其中找到它的obj(对象或数组)。


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;
}


如何使用它:



在数组中搜索键



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


在对象中搜索键


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


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

其它参考8


答案:


if ("key" in myObj)
{
    console.log("key exists!");
}
else
{
    console.log("key doesn't exist!");
}


说明:


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


因此,首先使用in运算符然后在知道密钥存在时比较密钥内的值是更好的做法。

其它参考9


vanila js


yourObjName.hasOwnProperty(key) : true ? false;


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


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

其它参考10


ES6解决方案



使用 Array#some Object.keys 。如果对象中存在给定键,则返回 true ;如果不存在,则返回 false [81] [82]




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');



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



underscore.js方式 - [83]


if(_.has(this.options, 'login')){
  //key 'login' exists in this.options 
}

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

其它参考11


这是一个老问题,但我想永远不会迟到给出答案。


想象一下,你有一个对象产品和两个项目。如果要查看此对象中是否已存在id,可以使用find()


products = [
    {
        "id": 1,
        "name": "Name 1"
    },
    {
        "id": 2,
        "name": "Name 2"
    },
  ]

  item1 = 
    {
        "id": 3,
        "name": "Name 3",
    }



  item2 = 
    {
        "id": 1,
        "name": "Name 1",
    }



  if(products.find(x => x.id === item1.id)){
    console.log('id is in products');
  }else {
    console.log('id is not in products');
  }
  if(products.find(x => x.id === item2.id)){
    console.log('id is in products');
  }else {
    console.log('id is not in products');
  }


日志:


id is not in products
id is in products

其它参考12


对于那些项目中包含lodash的人:
有一个lodash _.get方法试图获得深层键:




  获取object对象的值。如果解析的值未定义,
  defaultValue在其位置返回。[84]





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'
)

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>



虽然这必然检查密钥是否存在,但它会检查值的真实性。哪个undefinednull属于。


Boolean(obj.foo)


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

其它参考13


这些例子可以证明不同方式之间的差异。希望它能帮助您选择适合您需求的产品:


// 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"]