如何检查JavaScript对象或数组中是否存在特定键?
如果密钥不存在,并且我试图访问它,它会返回false吗?或者抛出错误?
如何检查JavaScript对象或数组中是否存在特定键?
如果密钥不存在,并且我试图访问它,它会返回false吗?或者抛出错误?
当前回答
快速回答
如何检查JavaScript对象或数组中是否存在特定键?如果密钥不存在,我尝试访问它,它会返回false吗?或者抛出错误?
使用(关联)数组样式或对象样式直接访问缺少的特性将返回未定义的常量。
缓慢而可靠的运算符和hasOwnProperty方法
正如人们在这里已经提到的,您可以有一个对象,其属性与“未定义”常量关联。
var bizzareObj = {valid_key: undefined};
在这种情况下,您必须使用hasOwnProperty或In运算符来确定密钥是否真的存在。但是,代价是什么?
所以,我告诉你。。。
in运算符和hasOwnProperty是使用Javascript中的属性描述符机制的“方法”(类似于Java语言中的Java反射)。
http://www.ecma-international.org/ecma-262/5.1/#sec-8.10
属性描述符类型用于解释命名属性属性的操作和具体化。属性描述符类型的值是由命名字段组成的记录,其中每个字段的名称是一个属性名称,其值是8.6.1中规定的相应属性值。此外,任何字段都可能存在或不存在。
另一方面,调用对象方法或键将使用Javascript[[Get]]机制。这快得多!
基准
https://jsben.ch/HaHQt
.
在运算符中使用
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
编辑:给属性分配未定义值的原因是什么?
这个问题困扰着我。在Javascript中,至少有两个对缺失对象的引用,以避免类似这样的问题:null和undefined。
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[].
劝告
避免使用未定义值的对象。只要可能,直接检查并使用null初始化属性值。否则,请使用slow-in运算符或hasOwnProperty()方法。
编辑:2018年4月12日-不再相关
正如人们所评论的那样,现代版本的Javascript引擎(除了firefox)改变了访问财产的方法。对于这种特定情况,当前的实现比之前的慢,但访问密钥和对象之间的差异可以忽略不计。
其他回答
虽然这不一定检查键是否存在,但它确实检查值的真实性。其中未定义和空值属于。
布尔(obj.foo)
这个解决方案最适合我,因为我使用了typescript,并且在obj或obj.hasOwnProperty('fo')中使用了像so'foo'这样的字符串检查密钥是否存在并不能为我提供智能感知。
这里有一个我觉得很有用的助手函数
此keyExists(key,search)可用于轻松查找对象或数组中的键!
只需将要查找的键传递给它,然后搜索要查找它的obj(对象或数组)。
函数keyExists(键,搜索){if(!search||(search.constructor!==数组&&search.constructionr!==对象)){return false;}for(var i=0;i<search.length;i++){if(搜索[i]==键){返回true;}}搜索中的返回键;}//如何使用://在数组中搜索关键字console.log(keyExists('apple',[apple','banana','orange']);//真的console.log(keyExists('水果',[苹果','香蕉','橙色']);//假的//在对象中搜索关键字console.log(keyExists('age',{'name':'Bill','age':29}));//真的console.log(keyExists('title',{'name':'Jason','age':29}));//假的
它非常可靠,跨浏览器运行良好。
在我的例子中,我想检查LUIS返回的NLP元数据,它是一个对象。我想检查一个字符串“FinancialRiskIntent”的键是否作为元数据对象中的键存在。
我试图将需要检查的嵌套对象作为目标->data.meta.precision.intents(仅出于我自己的目的,您的对象可以是任何对象)我使用以下代码检查密钥是否存在:
const hasKey=data.meta.prprediction.intents中的“财务风险意图”;if(hasKey){console.log('密钥存在。');}其他{console.log('密钥不存在。');}
这是在检查我最初寻找的特定密钥。
希望这一点对某人有所帮助。
const object1 = {
a: 'something',
b: 'something',
c: 'something'
};
const key = 's';
// Object.keys(object1) will return array of the object keys ['a', 'b', 'c']
Object.keys(object1).indexOf(key) === -1 ? 'the key is not there' : 'yep the key is exist';
可选链接运算符:
常量发票={客户:{地址:{城市:“foo”}}console.log(发票?.客户?.地址?.城市)console.log(发票?.客户?.地址?.街道)console.log(发票?.xyz?.address?.city)
查看支持的浏览器列表
对于那些在项目中包含lodash的人:有一个lodash_.get方法,它试图获取“深层”键:
获取对象路径处的值。如果解析值未定义,在其位置返回defaultValue。
var对象={‘a’:〔{‘b’:{‘c’:3}}〕};控制台日志(_.get(对象,'a[0].b.c'),//=>3_.get(对象,['a','0','b','c']),//=>3_.get(对象,'a.b.c'),//=>未定义_.get(对象,'a.b.c','default')//=>'default')<script src=“https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js“></script>
这将有效地检查是否定义了该键,无论该键有多深,如果未定义该键,则不会引发可能会损害程序流的错误。