如何检查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)改变了访问财产的方法。对于这种特定情况,当前的实现比之前的慢,但访问密钥和对象之间的差异可以忽略不计。
其他回答
ES6溶液
使用Array#some和Object.keys。如果给定的键存在于对象中,则返回true,否则返回false。
var obj={foo:'one',bar:'two'};函数isKeyInObject(obj,key){var res=对象.keys(obj).some(v=>v==key);console.log(res);}isKeyInObject(obj,'foo');isKeyInObject(obj,“something”);
单行示例。
console.log(Object.keys({foo:'one',bar:'two'}).some(v=>v=='foo'));
一个快速而简单的解决方案是将您的对象转换为json,然后您就可以完成这个简单的任务:
const allowed = {
'/login' : '',
'/register': '',
'/resetpsw': ''
};
console.log('/login' in allowed); //returns true
如果使用数组,则对象键将转换为整数(例如0,1,2,3等),因此,它将始终为false
使用“反射”的替代方法
根据MDN
Reflect是一个内置对象,它提供可拦截的方法JavaScript操作。静态Reflect.has()方法的工作方式类似于in运算符作用
变量obj={a: 未定义,b: 1中,c: “hello world”}console.log(Reflect.has(obj,“a”))console.log(Reflect.has(obj,'b'))console.log(Reflect.has(obj,“c”))console.log(Reflect.has(obj,“d”))
我应该使用它吗?
这取决于。
Reflect.has()比公认答案中提到的其他方法慢(根据我的基准测试)。但是,如果您只在代码中使用它几次,我看不出这种方法有多大问题。
这里有一个我觉得很有用的助手函数
此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}));//假的
它非常可靠,跨浏览器运行良好。
如果要检查对象上任何深度的任何键并考虑假值,请考虑实用函数的这一行:
var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;
后果
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