检查JavaScript对象中是否存在密钥?

Ada*_*nst 2750 javascript object

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

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

Ate*_*ral 3789

检查undefined-ness不是测试密钥是否存在的准确方法.如果密钥存在但值实际上undefined怎么办?

var obj = { key: undefined };
obj["key"] !== undefined // false, but the key exists!
Run Code Online (Sandbox Code Playgroud)

您应该使用in运算符:

"key" in obj // true, regardless of the actual value
Run Code Online (Sandbox Code Playgroud)

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

!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj   // ERROR!  Equivalent to "false in obj"
Run Code Online (Sandbox Code Playgroud)

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

obj.hasOwnProperty("key") // true
Run Code Online (Sandbox Code Playgroud)

对于那些方法之间的性能比较in,hasOwnProperty以及关键的是undefined,看到这个标杆

  • 我确信有一些用例可以将属性设置为未定义. (242认同)
  • 有效用例:Gecko 1.9.1 [Firefox 3.5]没有window.onhashchange属性.Gecko 1.9.2 [Firefox 3.6]将此属性设置为undefined(直到哈希更改).要检测哈希历史记录或浏览器版本,必须使用window.hasOwnProperty("onhashchange"); (159认同)
  • 拥有一个手动定义的undefined值的属性绝对没有意义.这真的是矛盾的. (78认同)
  • @joebert只是因为某些东西是胡说八道并不意味着你不会在生产代码中遇到它.有许多图书馆做无意义的事情. (70认同)
  • PHP中存在类似的问题,其中null ==不存在:http://stackoverflow.com/q/418066/372654,不幸的是,null也有用处. (7认同)
  • 很好,你提到使用括号.`!obj`中的"钥匙"已经咬了我很多次...... (3认同)
  • @joebert,可能没有用于在对象中手动实例化"undefined"的用例,但是如果你从某些第三方代码中获取对象,那么你永远不会知道并且应该为任何事情做好准备.特别是如果你自己开发一个库. (3认同)
  • 示例用例:考虑工程或科学计算.我想定义一个我知道我将需要的变量,但我不知道 - 但是 - 它的价值是什么.所以var x = undefined; 会做得很好...... (3认同)
  • 随机事实:设置为 `undefined` 的属性不会被 `JSON.stringify(...)` 序列化,而 `null` 会。因此,任何设置为 `undefined` 且返回到 JSON 的内容都会消失。您还可以使用`delete obj.propName` 从对象中删除属性。 (3认同)
  • 检查对象中的prop大约是在Chrome和Firefox中检查typeof = ='undefined'的两倍慢.IE和Safari混合了jsperf结果http://jsperf.com/object-properties-check/2 (2认同)
  • 我在某处看到了一个视频,建议您不要向变量明确分配“ undefined”,而当您要表示“ no value”时,建议不使用null,这是合理的,如果您遇到意外的“ undefined”,则表示您的代码未能在某个地方为变量分配初始值,如果相反,您会得到意外的“空”值,那么您知道有人明确分配了变量,但是您的代码逻辑并未遵循该规则进行处理。 (2认同)

rdl*_*pes 274

快速回答

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

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

缓慢和可靠运营商和hasOwnProperty方法

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

 var bizzareObj = {valid_key:  undefined};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您将必须使用hasOwnProperty运算符中知道密钥是否确实存在.但是,但是以什么价格?

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

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

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

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

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

基准

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

比较JS中的密钥访问.

运营商中 使用
var result = "Impression" in array;
Run Code Online (Sandbox Code Playgroud)

结果是

12,931,832 ±0.21% ops/sec      92% slower 
Run Code Online (Sandbox Code Playgroud) 使用hasOwnProperty
var result = array.hasOwnProperty("Impression")
Run Code Online (Sandbox Code Playgroud)

结果是

16,021,758 ±0.45% ops/sec     91% slower
Run Code Online (Sandbox Code Playgroud) 直接访问元素(括号样式)
var result = array["Impression"] === undefined
Run Code Online (Sandbox Code Playgroud)

结果是

168,270,439 ±0.13 ops/sec     0.02% slower 
Run Code Online (Sandbox Code Playgroud) 直接访问元素(对象样式)
var result = array.Impression  === undefined;
Run Code Online (Sandbox Code Playgroud)

结果是

168,303,172 ±0.20%     fastest
Run Code Online (Sandbox Code Playgroud)

编辑:为财产分配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[].
Run Code Online (Sandbox Code Playgroud)

劝告

避免使用undefined值的对象.尽可能直接检查并用于null初始化属性值.否则,请使用慢速in运算符或hasOwnProperty()方法.

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

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

  • +1用于基准测试.谢谢,这正是我希望找到的信息.绝对是编写代码的强有力的论据,它永远不会指定或期望一个键包含值**undefined**. (9认同)
  • 我将undefined设置为哈希值的一个原因是我实际上想从哈希中删除该属性键,但是`delete hash [key]`比[慢得多](http://jsperf.com/delete-vs -undefined-vs-null/16)`hash [key] = undefined`.当然在这种情况下,对我来说没有必要使用`in`操作符,但它作为一个反例,"我们应该总是避免将值设置为undefined". (3认同)

Eli*_*ght 132

它会回来undefined.

var aa = {hello: "world"};
alert( aa["hello"] );      // popup box with "world"
alert( aa["goodbye"] );    // popup box with "undefined"
Run Code Online (Sandbox Code Playgroud)

undefined是一个特殊的常数值.所以你可以说,例如

// note the three equal signs so that null won't be equal to undefined
if( aa["goodbye"] === undefined ) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

这可能是检查丢失密钥的最佳方法.但是,正如下面的评论所指出的那样,理论上你可能希望得到实际值undefined.我从来不需要这样做,也不能想出我为什么要这样做的理由,但为了完整起见,你可以使用in运算符

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

  • 在与undefined进行比较时,您应该使用===而不是==,否则null将比较等于undefined. (13认同)
  • Eli你的答案并不完全准确.因为无论如何(当然不应该这样做)undefined不是一个特殊的常量值.事实上,它不是一个保留的关键字,你可以覆盖它,比如说,`var undefined = 42;`.在测试未定义的道具时,你应该总是使用`((typeof variable)==="undefined")`. (10认同)
  • 如果密钥存在但值实际上未定义怎么办? (8认同)

Ran*_*ner 57

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

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

const person = { name: 'dan' };

console.log('name' in person); // true
console.log('age' in person); // false
Run Code Online (Sandbox Code Playgroud)

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

*2021 - 使用新方法***Object.hasOwn()作为替代Object.hasOwnProperty()

Object.hasOwn()旨在替代 Safari,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
Run Code Online (Sandbox Code Playgroud)

使用它而不是 Object.prototype.hasOwnProperty 的动机是什么?- 建议使用此方法而不是 ,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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

更多信息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


han*_*dle 28

接受的答案是指对象.小心使用in运营商阵列,以寻找数据,而不是键:

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

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


小智 24

"key" in obj
Run Code Online (Sandbox Code Playgroud)

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


Lav*_*dor 21

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

  1. !! obj.theProperty
    将值转换为bool.除"false"值之外的所有值都返回TRUE
  2. obj中的'theProperty'
    如果属性存在则返回true,无论其值是多少(甚至为空)
  3. obj.hasOwnProperty('theProperty')
    不检查原型链.(因为所有对象都有'toString'方法,1和2将在其上返回true,而3可以在其上返回false.)

参考:

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

  • 评论:“!!obj.theProperty”不是检查对象是否具有名为“theProperty”的属性的解决方案。对于任何错误的属性值、`undefined`、null、数字`0`或`NaN`以及空字符串`""`,它都会失败 (3认同)

Nic*_*oks 15

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

Object.keys(obj).includes(key)

ES7 include方法检查数组是否包含项目, & 是 的更简单替代方案indexOf


vat*_*sal 13

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

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

yourArray = {age: "10"}

_.has(yourArray, "age")
Run Code Online (Sandbox Code Playgroud)

返回true

但,

_.has(yourArray, "invalidKey")
Run Code Online (Sandbox Code Playgroud)

返回false


Web*_*eng 13

回答:

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

说明:

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

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


Adi*_*ari 10

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

来源:MDN/Operators/Optional_chaining

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
}

console.log(adventurer.dog?.name) // undefined
console.log(adventurer.cat?.name) // Dinah
Run Code Online (Sandbox Code Playgroud)


jar*_*lli 9

这是一个我发现非常有用的辅助函数

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 Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false
Run Code Online (Sandbox Code Playgroud)

如何使用它:

在数组中搜索键

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 Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false
Run Code Online (Sandbox Code Playgroud)

在对象中搜索键

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 Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false
Run Code Online (Sandbox Code Playgroud)

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

  • 这看起来有点困惑:首先,在搜索数组时,此方法检查的是_value_,而不是密钥.其次,当你可以使用内置的[`Array.indexOf`]时,为什么要迭代这样的数组(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)方法?(如果你正在寻找一个值,那就是) (6认同)

Haj*_*rik 7

vanila js

yourObjName.hasOwnProperty(key) : true ? false;
Run Code Online (Sandbox Code Playgroud)

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

Object.keys(yourObjName).length : true ? false
Run Code Online (Sandbox Code Playgroud)


vsy*_*ync 7

可选链操作符

const invoice = {customer: {address: {city: "foo"}}}

console.log( invoice?.customer?.address?.city )
console.log( invoice?.customer?.address?.street )
console.log( invoice?.xyz?.address?.city )
Run Code Online (Sandbox Code Playgroud)

查看支持的浏览器列表


对于那些lodash包含在他们的项目中的人:
有一个 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'
)
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


这将有效地检查该键是否已定义,无论该键有多,并且如果未定义该键,则不会抛出可能会损害程序流程的错误。


she*_*dtu 7

最简单的检查方法是

"key" in object
Run Code Online (Sandbox Code Playgroud)

例如:

var obj = {
  a: 1,
  b: 2,
}
"a" in obj // true
"c" in obj // false
Run Code Online (Sandbox Code Playgroud)

返回值为true意味着该对象中存在键。


Rup*_*pam 6

使用“反射”的替代方法

根据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'))
Run Code Online (Sandbox Code Playgroud)

我应该使用它吗?

这取决于。

Reflect.has()比接受的答案中提到的其他方法慢(根据我的基准测试)。但是,如果您在代码中只使用它几次,我认为这种方法没有太多问题。


Moh*_*ere 5

我们可以用 - 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);
};
Run Code Online (Sandbox Code Playgroud)


kin*_*ser 5

ES6解决方案

使用Array#someObject.keys.如果对象中存在给定键,则返回true,否则返回false.

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');
Run Code Online (Sandbox Code Playgroud)

单行示例.

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


rea*_*pie 5

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

Boolean(obj.foo)

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


Ale*_*lex 5

如果要检查对象上任何深度的任何键并考虑错误值,请考虑使用以下行作为实用函数:

var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;
Run Code Online (Sandbox Code Playgroud)

结果

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
Run Code Online (Sandbox Code Playgroud)

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