检查JavaScript对象中是否存在键?

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

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

3157720 次浏览

它将返回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 undefinedif( aa["goodbye"] === undefined ) {// do something}

这可能是检查缺失键的最佳方法。然而,正如下面的评论中指出的,理论上你可能希望实际值为undefined。我从来不需要这样做,也想不出我想要这样做的原因,但只是为了完整性,你可以使用in运算符

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

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

var obj = { key: undefined };console.log(obj["key"] !== undefined); // false, but the key exists!

你应该使用in运算符:

var obj = { key: undefined };console.log("key" in obj); // true, regardless of the actual value

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

var obj = { not_key: undefined };console.log(!("key" in obj)); // true if "key" doesn't exist in objectconsole.log(!"key" in obj);   // Do not do this! It is equivalent to "false in obj"

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

var obj = { key: undefined };console.log(obj.hasOwnProperty("key")); // true

有关inhasOwnProperty和key为undefined的方法之间的性能比较,请参阅这个基准

基准测试结果

"key" in obj

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

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

  1. #0
    将值转换为布尔。除了false
  2. 之外,所有值都返回true
  3. obj中的#0
    如果属性存在,则返回true,无论其值(甚至为空)
  4. #0
    不检查原型链。(因为所有对象都有toString方法,1和2将在其上返回true,而3可以在其上返回false。)

参考:

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

快速回答

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

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

缓慢而可靠的算子和hasOwnProperty方法

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

 var bizzareObj = {valid_key:  undefined};

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

所以我告诉你…

运算符和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

比较JS中的密钥访问

使用运算符

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除外)已经改变了访问属性的方法。对于这种特殊情况,当前的实现比之前的实现慢,但访问键和对象之间的区别是可以忽略的。

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

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

yourArray = {age: "10"}
_.has(yourArray, "age")

返回真正

但是,

_.has(yourArray, "invalidKey")

返回虚假

接受的答案指的是对象。注意使用数组上的#0运算符来查找数据而不是键:

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

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

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

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;}
// How to use it:// Searching for keys in Arraysconsole.log(keyExists('apple', ['apple', 'banana', 'orange'])); // trueconsole.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false
// Searching for keys in Objectsconsole.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // trueconsole.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false

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

答复:

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

说明:

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

因此,更好的做法是首先使用in运算符,然后在您已经知道它存在后比较键内部的值。

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

underscore.js方式-

if(_.has(this.options, 'login')){//key 'login' exists in this.options}
_.has = function(obj, key) {return hasOwnProperty.call(obj, key);};

vanilajs

yourObjName.hasOwnProperty(key) : true ? false;

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

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

es6解决方案

使用#0#1。如果对象中存在给定的键,它将返回真正,如果不存在,则返回虚假

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

单行示例。

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

可选链接运算符

const invoice = {customer: {address: {city: "foo"}}}
console.log( invoice?.customer?.address?.city )console.log( invoice?.customer?.address?.street )console.log( invoice?.xyz?.address?.city )

查看支持的浏览器列表


对于那些在他们的项目中包含lodash的人:
有一个洛塔什_. get方法试图获得“深”键:

获取对象路径处的值。如果解析值未定义,默认值将在其位置返回。

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>


This will effectively check if that key, however deep, is defined and will not throw an error which might harm the flow of your program if that key is not defined.

虽然这不一定检查键是否存在,但它确实检查值的真实性。undefinednull属于哪个。

Boolean(obj.foo)

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

这些例子可以展示不同方式之间的差异。希望它能帮助你根据自己的需要选择正确的方法:

// 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; // 2a.onProtUndef; // undefineda.ownProp; // 3a.ownPropUndef; // undefineda.whatEver; // undefineda.valueOf; // ƒ valueOf() { [native code] }
a.hasOwnProperty('onProtDef'); // falsea.hasOwnProperty('onProtUndef'); // falsea.hasOwnProperty('ownProp'); // truea.hasOwnProperty('ownPropUndef'); // truea.hasOwnProperty('whatEver'); // falsea.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"]

JavaScript解构的新解决方案:

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 key4if(!key4) { console.log("key not present"); } // Key not present

检查JavaScript解构的其他用途

如果您想检查对象上任何深度的任何键并考虑假值,请考虑这行实用函数:

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, "")> falsekeyExistsOn(obj, "locals.test")> truekeyExistsOn(obj, "locals.test2")> truekeyExistsOn(obj, "locals.test3")> truekeyExistsOn(obj, "locals.test4")> truekeyExistsOn(obj, "locals.test5")> truekeyExistsOn(obj, "sdsdf")falsekeyExistsOn(obj, "sdsdf.rtsd")falsekeyExistsOn(obj, "sdsdf.234d")falsekeyExistsOn(obj, "2134.sdsdf.234d")falsekeyExistsOn(obj, "locals")truekeyExistsOn(obj, "locals.")falsekeyExistsOn(obj, "locals.auth")truekeyExistsOn(obj, "locals.autht")falsekeyExistsOn(obj, "locals.auth.")falsekeyExistsOn(obj, "locals.auth.user")truekeyExistsOn(obj, "locals.auth.userr")falsekeyExistsOn(obj, "locals.auth.user.")falsekeyExistsOn(obj, "locals.auth.user")true

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

最简单的检查方法是

"key" in object

例如:

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

返回值为真正意味着键存在于对象中。

yourArray.indexOf(Your ArrayKeyName)>-1

fruit = ['apple', 'grapes', 'banana']
fruit.indexOf('apple') > -1

真正


fruit = ['apple', 'grapes', 'banana']
fruit.indexOf('apple1') > -1

虚假


对于严格的对象键检查:

const object1 = {};object1.stackoverflow = 51;console.log(object1.hasOwnProperty('stackoverflow'));


output: true
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';

在“数组”世界中,我们可以将索引视为某种键。令人惊讶的是in运算符(这是对象的不错选择)也适用于数组。不存在键的返回值是undefined

let arr = ["a","b","c"]; // we have indexes: 0,1,2delete arr[1];           // set 'empty' at index 1arr.pop();               // remove last item
console.log(0 in arr,  arr[0]);console.log(1 in arr,  arr[1]);console.log(2 in arr,  arr[2]);

一个快速简单的解决方案是将您的对象转换为json,然后您将能够完成这个简单的任务:

const allowed = {'/login' : '','/register': '','/resetpsw': ''};console.log('/login' in allowed); //returns true

如果您使用数组,对象键将转换为整数ex 0,1,2,3等,因此它将始终为假

可选链接?.)运算符也可用于此

来源:#0

const adventurer = {name: 'Alice',cat: {name: 'Dinah'}}
console.log(adventurer.dog?.name) // undefinedconsole.log(adventurer.cat?.name) // Dinah

在我的例子中,我想检查LUIS返回的NLP元数据,它是一个对象。我想检查一个字符串“FinantialRiskIntent”的键是否作为该元数据对象中的键存在。

  1. 我尝试定位我需要检查的嵌套对象->data.meta.prediction.intents(仅出于我自己的目的,您的对象可以是任何对象)
  2. 我使用下面的代码来检查密钥是否存在:

const hasKey = 'FinancialRiskIntent' in data.meta.prediction.intents;
if(hasKey) {console.log('The key exists.');}else {console.log('The key does not exist.');}

这是检查我最初寻找的特定密钥。

希望这一点能帮助到别人。

值得注意的是,自ES11引入以来,您可以使用nul的合并运算符,这大大简化了事情:

const obj = {foo: 'one', bar: 'two'};
const result = obj.foo ?? "Not found";

上面的代码对于foo中的任何“false sy”值都将返回“未找到”。否则它将返回obj.foo.

结合零合并运算符

  1. 检查对象的属性,包括继承的属性

可以使用in运算符确定,如果指定的属性在指定的对象或其原型链中,则返回true,否则返回false

const person = { name: 'dan' };
console.log('name' in person); // trueconsole.log('age' in person); // false

  1. 检查对象实例的属性(不包括继承的属性)

*2021-使用新方法***#0作为#1的替代品

Object.hasOwn()旨在替代Object.hasOwnProperty(),是一种可供使用的新方法(但仍未被Safari等所有浏览器完全支持,但很快就会支持)

Object.hasOwn()是一个静态方法,如果指定的对象具有指定的属性作为自己的属性,则返回true。如果该属性被继承或不存在,则该方法返回false。

const person = { name: 'dan' };
console.log(Object.hasOwn(person, 'name'));// trueconsole.log(Object.hasOwn(person, 'age'));// false
const person2 = Object.create({gender: 'male'});
console.log(Object.hasOwn(person2, 'gender'));// false

在OwnProperty上使用它Object.prototype.has动机是什么?-建议在Object.hasOwnProperty()上使用此方法,因为它也适用于使用Object.create(null)创建的对象和覆盖了继承的hasOwnProperty()方法的对象。虽然可以通过在外部对象上调用Object.prototype.hasOwnProperty()来解决此类问题,但Object.hasOwn()克服了这些问题,因此是首选(参见下面的示例)

let person = {hasOwnProperty: function() {return false;},age: 35};
if (Object.hasOwn(person, 'age')) {console.log(person.age); // true - the remplementation of hasOwnProperty() did not affect the Object}

let person = Object.create(null);person.age = 35;if (Object.hasOwn(person, 'age')) {console.log(person.age); // true - works regardless of how the object was created}

更多关于Object.hasOwn的信息可以在这里找到:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn

Object.hasOwn-https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility的浏览器兼容性

使用“反射”的替代方法

根据MDN

Reflect是一个内置对象,提供可拦截的方法JavaScript操作。

静态Reflect.has()方法的工作方式与in运算符类似函数。

var obj = {a: undefined,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()比公认答案中提到的其他方法慢(根据我的基准测试)。但是,如果你在代码中只使用了几次,我不认为这种方法有什么问题。

JS双感叹号!!标志可能会在这种情况下有所帮助。

const cars = {petrol:{price: 5000},gas:{price:8000}}

假设我们有上面的对象,如果你试图登录汽车与汽油价格。

=> console.log(cars.petrol.price);=> 5000

你肯定会从中得到5000。但是如果你试图得到一个如果没有电动汽车,你会得到undefine

=> console.log(cars.electric);=> undefine

但是使用!!这是将变量转换为布尔值(true或false)。

=> console.log(!!cars.electric);=> false

要查找对象中是否存在键,请使用

Object.keys(obj).includes(key)

ES7包括方法检查Array是否包含项目,&是indexOf的更简单的替代方案。

const rawObject = {};rawObject.propertyKey = 'somethingValue';
console.log(rawObject.hasOwnProperty('somethingValue'));// expected output: true

检查给定对象中存在的特定键,hasOwnProperty将在此处工作。

如果您在项目中配置了ESLint,请遵循ESLint规则无原型-内置于s。原因已在以下链接中描述:

// badconsole.log(object.hasOwnProperty(key));
// goodconsole.log(Object.prototype.hasOwnProperty.call(object, key));
// bestconst has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.console.log(has.call(object, key));/* or */import has from 'has'; // https://www.npmjs.com/package/hasconsole.log(has(object, key));