如何检查 JavaScript 对象或数组中是否存在特定键?
如果密钥不存在,而我尝试访问它,它会返回 false 吗?还是抛出错误?
property.key = property.key || 'some default value'
,以防我希望该键存在并具有一定的价值
检查未定义性并不是测试密钥是否存在的准确方法。如果键存在但值实际上是 undefined
怎么办?
var obj = {键:未定义}; console.log(obj["key"] !== undefined); // false,但是密钥存在!
您应该改用 in
运算符:
var obj = {键:未定义}; console.log("key" in obj); // true,与实际值无关
如果要检查键是否不存在,请记住使用括号:
var obj = { not_key: undefined }; console.log(!("key" in obj)); // 如果对象中不存在“key”,则为 true console.log(!"key" in obj); // 不要这样做!相当于“obj中的假”
或者,如果您想特别测试对象实例的属性(而不是继承的属性),请使用 hasOwnProperty
:
var obj = {键:未定义}; console.log(obj.hasOwnProperty("key")); // 真的
对于 in
、hasOwnProperty
和 key 是 undefined
的方法之间的性能比较,请参阅 this benchmark:
https://i.stack.imgur.com/PEuZT.png
快速回答
如何检查 JavaScript 对象或数组中是否存在特定键?如果密钥不存在而我尝试访问它,它会返回 false 吗?还是抛出错误?
使用(关联)数组样式或对象样式直接访问缺少的属性将返回未定义的常量。
operator 和 hasOwnProperty 方法中缓慢可靠
正如人们在这里已经提到的那样,您可以拥有一个具有与“未定义”常量关联的属性的对象。
var bizzareObj = {valid_key: undefined};
在这种情况下,您将不得不使用 hasOwnProperty 或 in 运算符来了解密钥是否真的存在。但是,但是以什么价格?
所以,我告诉你...
in 运算符和 hasOwnProperty 是在 Javascript 中使用 Property Descriptor 机制的“方法”(类似于 Java 语言中的 Java 反射)。
http://www.ecma-international.org/ecma-262/5.1/#sec-8.10
属性描述符类型用于解释命名属性属性的操作和具体化。属性描述符类型的值是由命名字段组成的记录,其中每个字段的名称是属性名称,其值是 8.6.1 中指定的相应属性值。此外,任何字段都可以存在或不存在。
另一方面,调用对象方法或键将使用 Javascript [[Get]] 机制。那速度要快得多!
基准
https://i.stack.imgur.com/GjzNU.png
使用 in 运算符
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
是未知值(未定义)。如果有一个属性稍后将与 proper 值一起使用,请考虑使用 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()
方法。
编辑:2018 年 12 月 4 日 - 不再相关
正如人们评论的那样,现代版本的 Javascript 引擎(Firefox 例外)已经改变了访问属性的方法。对于这种特殊情况,当前实现比以前的实现要慢,但访问密钥和对象之间的差异可以忽略不计。
它将返回 undefined
。
var aa = {你好:“世界”};警报(aa [“你好”]); // 带有 "world" 的弹出框 alert(aa["goodbye"] ); // 带有“未定义”的弹出框
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
}
"key" in obj
可能只测试与数组键非常不同的对象属性值
accepted answer 指的是 Object。请注意使用 Array 上的 in
operator 来查找数据而不是键:
("true" in ["true", "false"])
// -> false (Because the keys of the above Array are actually 0 and 1)
要测试数组中的现有元素:Best way to find if an item is in a JavaScript array?
检查 javascript 对象中是否存在属性的三种方法:
!!obj.theProperty 将值转换为布尔值。 obj.hasOwnProperty('theProperty') 不检查原型链。 (因为所有对象都有 toString 方法,所以 1 和 2 会返回 true,而 3 会返回 false。)
参考:
http://book.mixu.net/node/ch5.html
var a = {a : undefined, b : null}; !!a.a **will return false**
!!obj.theProperty
不是检查对象是否具有名为 theProperty
的属性的解决方案。对于任何虚假属性值、undefined
、null、数字 0
或 NaN
以及空字符串 ""
,它都会失败
检查对象的属性,包括继承的属性
可以使用 in
运算符确定,如果指定的属性在指定的对象或其原型链中,则返回 true,否则返回 false
const person = { name: 'dan' }; console.log('name' 本人); // true console.log('age' in person); // 错误的
检查对象实例的属性(不包括继承的属性)
*2021 - 使用新方法 ***Object.hasOwn()
作为 Object.hasOwnProperty()
的替代品
Object.hasOwn()
旨在替代 Object.hasOwnProperty()
,是一种可供使用的新方法(但尚未得到 safari 等所有浏览器的完全支持,但很快就会支持)
Object.hasOwn()
是一个静态方法,如果指定对象具有指定属性作为其自己的属性,则返回 true。如果属性被继承或不存在,则该方法返回 false。
const person = { name: 'dan' }; console.log(Object.hasOwn(person, 'name'));// true console.log(Object.hasOwn(person, 'age'));// false const person2 = Object.create({gender: 'male '}); console.log(Object.hasOwn(person2, 'gender'));// false
在 Object.prototype.hasOwnProperty 上使用它的动机是什么? - 建议在 Object.hasOwnProperty()
上使用此方法,因为它也适用于使用 Object.create(null)
创建的对象以及已覆盖继承的 hasOwnProperty()
方法。虽然可以通过在外部对象上调用 Object.prototype.hasOwnProperty()
来解决这类问题,但 Object.hasOwn()
克服了这些问题,因此是首选(参见下面的示例)
让 person = { hasOwnProperty: function() { return false; }, 年龄: 35 }; if (Object.hasOwn(person, 'age')) { console.log(person.age); // true - hasOwnProperty() 的实现不影响 Object }
让人 = Object.create(null);人.年龄 = 35; if (Object.hasOwn(person, 'age')) { console.log(person.age); // true - 无论对象是如何创建的都有效 }
可以在此处找到有关 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 的浏览器兼容性
如果您使用的是 underscore.js 库,那么对象/数组操作就会变得简单。
在您的情况下,可以使用 _.has 方法。例子:
yourArray = {age: "10"}
_.has(yourArray, "age")
返回真
但,
_.has(yourArray, "invalidKey")
返回假
回答:
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)
可用于轻松查找对象或数组中的键!
只需将您想要查找的键传递给它,然后搜索您想要在其中找到它的 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; } } 返回搜索键; } // 如何使用它: // 在数组中搜索键 console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false // 在对象中搜索键 console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // 错误的
它非常可靠并且跨浏览器运行良好。
Array.indexOf
方法,为什么还要遍历这样的数组呢? (如果你正在寻找一个价值,那就是)
香草js
yourObjName.hasOwnProperty(key) : true ? false;
如果要检查对象在 es2015 中是否至少有一个属性
Object.keys(yourObjName).length : true ? false
ES6 解决方案
使用 Array#some
和 Object.keys
。如果对象中存在给定的键,它将返回 true,否则返回 false。
var obj = {foo: '一个', bar: '两个'};函数 isKeyInObject(obj, key) { var res = Object.keys(obj).some(v => v == key);控制台.log(res); } isKeyInObject(obj, 'foo'); isKeyInObject(obj, '某事');
单行示例。
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 ) 控制台。日志(发票?.xyz?.地址?.城市)
对于那些在他们的项目中包含 lodash 的人:有一个 lodash _.get 方法试图获取“深”键:
获取对象路径的值。如果解析的值未定义,则在其位置返回 defaultValue。
var object = { 'a': [{ 'b': { 'c': 3 } }] }; console.log( _.get(object, 'a[0].bc'), // => 3 _.get(object, ['a', '0', 'b', 'c']), // => 3 _.get(object, 'abc'), // => undefined _.get(object, 'abc', 'default') // => 'default' )
这将有效地检查该键(无论多么深)是否已定义,并且如果未定义该键,则不会引发可能损害程序流程的错误。
最简单的检查方法是
"key" in object
例如:
var obj = {
a: 1,
b: 2,
}
"a" in obj // true
"c" in obj // false
返回值为 true 意味着 key 存在于对象中。
要查找对象中是否存在键,请使用
Object.keys(obj).includes(key)
ES7 includes 方法检查 Array 是否包含项目,&是 indexOf
的一个更简单的替代方案。
可选链接 (?.
) 运算符也可用于此
来源:MDN/Operators/Optional_chaining
const Adventurer = { name: 'Alice', cat: { name: 'Dinah' } } console.log(adventurer.dog?.name) // undefined console.log(adventurer.cat?.name) // Dinah
我们可以使用 - 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);
};
如果您想检查对象上任何深度的任何键并考虑错误值,请考虑使用此行作为实用函数:
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
虽然这不一定检查密钥是否存在,但它确实检查了值的真实性。 undefined
和 null
属于哪个。
Boolean(obj.foo)
这个解决方案最适合我,因为我使用打字稿,并且使用像 'foo' in obj
或 obj.hasOwnProperty('foo')
这样的字符串来检查密钥是否存在并不能为我提供智能感知。
使用“反射”的替代方法
根据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')) 控制台.log(Reflect.has(obj, 'c')) console.log(Reflect.has(obj, 'd'))
我应该使用它吗?
这取决于。
Reflect.has()
比接受答案中提到的其他方法慢(根据我的基准测试)。但是,如果您在代码中只使用它几次,我看不出这种方法有太多问题。
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
让 arr = ["a","b","c"]; // 我们有索引:0,1,2 delete arr[1]; // 在索引 1 处设置 'empty' arr.pop(); // 删除最后一项 console.log(0 in arr, arr[0]); console.log(1 in arr, arr[1]); console.log(2 in arr, arr[2]);
值得注意的是,自从 ES11 引入以来,您可以使用 nullish coalescing 运算符,这大大简化了事情:
const obj = {foo: 'one', bar: 'two'};
const result = obj.foo ?? "Not found";
上面的代码将为 foo 中的任何“虚假”值返回“未找到”。否则它将返回 obj.foo。
请参阅Combining with the nullish coalescing operator
JS 双感叹号 !!
符号在这种情况下可能会有所帮助。
const cars = {
petrol:{
price: 5000
},
gas:{
price:8000
}
}
假设我们有上面的对象,如果您尝试用汽油价格记录汽车。
=> console.log(cars.petrol.price);
=> 5000
你肯定会从中得到5000。但是,如果您尝试获得一辆不存在的电动汽车怎么办,那么您将无法定义
=> console.log(cars.electric);
=> undefine
但是使用!!这是将变量转换为布尔(真或假)值的捷径。
=> console.log(!!cars.electric);
=> false
就我而言,我想检查 LUIS 返回的 NLP 元数据,它是一个对象。我想检查作为字符串“FinancialRiskIntent”的键是否作为该元数据对象中的键存在。
我试图定位我需要检查的嵌套对象-> data.meta.prediction.intents(仅出于我自己的目的,您的可以是任何对象)我使用下面的代码来检查密钥是否存在:
const hasKey = 'FinancialRiskIntent' in data.meta.prediction.intents; if(hasKey) { console.log('密钥存在。'); } else { console.log('密钥不存在。'); }
这是检查我最初寻找的特定密钥。
希望这对某人有所帮助。
这些例子可以展示不同方式之间的差异。希望它能帮助您选择适合您需求的产品:
// 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"]
const rawObject = {};
rawObject.propertyKey = 'somethingValue';
console.log(rawObject.hasOwnProperty('somethingValue'));
// expected output: true
检查给定对象中存在的特定键,hasOwnProperty 将在这里工作。
如果您在项目中配置了 ESLint,则遵循 ESLint 规则 no-prototype-builtins。原因已在以下链接中描述:
// bad
console.log(object.hasOwnProperty(key));
// good
console.log(Object.prototype.hasOwnProperty.call(object, key));
// best
const 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/has
console.log(has(object, key));
yourArray.indexOf(yourArrayKeyName) > -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
使用 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 key4
if(!key4) { console.log("key not present"); } // Key not present
请检查other use of JavaScript Destructuring
undefined
的属性不会被JSON.stringify(...)
序列化,而null
会。因此,任何设置为undefined
且往返于 JSON 的内容都将消失。您还可以使用delete obj.propName
从对象中删除属性。