如何检查对象中键是否存在?

avatar
作者
筋斗云
阅读量:0

在开发过程中,我们经常会遇到需要检查对象中是否存在某个键的情况。这可能是为了从对象中获取值,或者是为了判断某个功能是否可用。如何正确有效地执行此操作是很重要的。

本文将介绍四种常用的方法来检查 JavaScript 对象中的键是否存在:

1. 使用 in 操作符

JavaScript 中的 in 操作符用于检查一个指定的属性是否存在于某个对象中。如果该属性存在,in 操作符将返回 true;否则,返回 false

注意:in 操作符不仅会检查对象本身的属性,还会检查它继承的属性(原型链上的属性)。因此,如果您只想检查对象本身的属性,in 操作符可能无法满足您的需求。

代码示例

const user = {   name: "John Doe",   age: 30,   occupation: "Software Engineer" };  console.log("name" in user); // true console.log("age" in user); // true console.log("address" in user); // false 

优点

  • 简单易用
  • 性能良好,复杂度为 O(1)

缺点

  • 不能区分继承或原型链上的属性

2. 使用 hasOwnProperty 方法

hasOwnProperty 是 JavaScript 对象的一个方法,其作用与 in 操作符类似,都是用于检查对象中是否存在某个属性。但是,hasOwnProperty 方法只检查对象本身的属性,不会 沿着原型链去查找继承的属性。因此,hasOwnProperty 方法返回的结果会更有针对性。

代码示例

const user = {   name: "John Doe",   age: 30,   occupation: "Software Engineer" };  console.log(user.hasOwnProperty("name")); // true console.log(user.hasOwnProperty("age")); // true console.log(user.hasOwnProperty("address")); // false 

优点

  • 可以区分继承或原型链上的属性
  • 性能良好,复杂度为 O(1)

缺点

  • 语法略显繁琐

3. 使用可选链(Optional Chaining)

可选链是 ES11 引入的一项特性,用于安全地访问嵌套对象的属性,避免因属性不存在而抛出错误。当键(属性名)不存在时,可选链会返回 undefined;如果键存在,则会返回对应的值。

小技巧:为了将可选链的结果转换为布尔值(true 或 false),可以在表达式的最前面加上 !!(逻辑非运算符执行两次,相当于将值转为布尔值)。

代码示例

const user = {   name: "John Doe",   age: 30,   occupation: "Software Engineer" };  console.log(user?.name); // "John Doe" console.log(user?.age); // 30 console.log(user?.address); // undefined console.log(!!user?.address); // false 

优点

  • 语法简洁
  • 可以安全地访问可能不存在的键
  • 性能良好,复杂度为 O(1)

缺点

  • 仅适用于 ES11 或更高版本
  • 如果值是 falsy 值(如 false0undefinednull),即使键存在也会返回 false

4. 遍历所有键进行比较

在我们介绍的几种检查对象键是否存在的方法中,遍历所有键进行比较是一种效率较低的方法。因为它方法涉及手动迭代对象的所有键,并逐个检查是否存在指定的键。

代码示例

const isKeyExistInObject = (obj, key) => {   return Object.keys(obj).some(eachKey => eachKey === key); };  const user = {   name: "John Doe",   age: 30,   occupation: "Software Engineer" };  console.log(isKeyExistInObject(user, "name")); // true console.log(isKeyExistInObject(user, "age")); // true console.log(isKeyExistInObject(user, "address")); // false 

在上面的代码中,我们定义了一个名为 isKeyExistInObject 的函数,用于检查对象中是否存在指定的键。

函数首先使用 Object.keys(obj) 方法将对象的所有键转换为数组。

然后,它使用 find 方法遍历该数组,检查是否存在与指定键(key 参数)相同的元素。

  • 如果找到匹配的键,find 方法会返回该键本身(eachKey)。
  • 如果找不到匹配的键,find 方法会返回 undefined

为了将找到的键或 undefined 值转换为布尔值 (true 或 false),代码使用了逻辑非运算符 (!!) 一次或两次。这相当于使用 Boolean(value) 构造函数进行类型转换。

优点

  • 可以处理任何类型的值,包括 falsy 值
  • 适用于任何版本的 JavaScript

缺点

  • 性能较差,复杂度为 O(n),其中 n 是对象中键的数量

完整示例

我们将使用同一个对象,展示不同的检查方式,

const  user  = {     name: "john Doe",     age: 22,     studentData: {         id: "123",         bachelor: "CSE",         countryData: {             country: "Bangladesh",             capital: "Dhaka",             language: "Bangla",         },     }, }; 

使用 in

// ==========  检查 "name" 属性是否存在于 user 对象中 console.log("name"  in  user); // true  // ========== 检查 "studentData" 属性是否存在于 user 对象中 console.log("studentData"  in  user); // true  // ========== 检查 "studentData" 属性是否存在于 user 对象中 console.log(     "studentData"  in  user  &&  "id"  in  user.studentData ); // true  // ========== 检查 "language" 属性是否存在于 user.studentData.countryData 对象中 console.log(     "studentData"  in  user  &&     "countryData"  in  user.studentData  &&     "language"  in  user.studentData.countryData ); // true 

使用 hasOwnProperty

// ========== 检查 "name" 属性是否存在于 user 对象中 console.log(user.hasOwnProperty("name")); // true  // ========== 检查 "studentData" 属性是否存在于 user 对象中 console.log(user.hasOwnProperty("studentData")); // true  // ========== 检查 "id" 属性是否存在于 user.studentData 对象中 console.log(     user.hasOwnProperty("studentData") &&      user.studentData.hasOwnProperty("id") ); // true  // ========== 检查 "language" 属性是否存在于 user.studentData.countryData 对象中 console.log(     user.hasOwnProperty("studentData") &&     user.studentData.hasOwnProperty("countryData") &&     user.studentData.countryData.hasOwnProperty("language") ); // true 

使用可选链

// ==========  检查 "name" 属性是否存在于 user 对象中 console.log(!!user?.name); // true  // ========== 检查 "studentData" 属性是否存在于 user 对象中 console.log(!!user?.studentData); // true  // ========== 检查 "studentData" 属性是否存在于 user 对象中 console.log(     !!user?.studentData  &&  !!user.studentData?.id ); // true  // ========== 检查 "language" 属性是否存在于 user.studentData.countryData 对象中 console.log(     !!user?.studentData  &&     !!user.studentData?.countryData  &&     !!user.studentData.countryData?.language ); // true 

比较所有键

const  isKeyExistInObject  = (obj, key) => {     return  !!Object.keys(obj).find(         (eachKey) =>  eachKey  ===  key     ); };  // ==========  检查 "name" 属性是否存在于 user 对象中 console.log(isKeyExistInObject(user, "name")); // true  // ========== 检查 "studentData" 属性是否存在于 user 对象中 console.log(isKeyExistInObject(user, "studentData")); // true  // ========== 检查 "studentData" 属性是否存在于 user 对象中 console.log(     isKeyExistInObject(user, "studentData") &&     isKeyExistInObject(user.studentData, "id") ); // true  // ========== 检查 "language" 属性是否存在于 user.studentData.countryData 对象中 console.log(     isKeyExistInObject(user, "studentData") &&     isKeyExistInObject(user.studentData, "countryData") &&     isKeyExistInObject(user.studentData.countryData, "language") ); // true 

如何选择合适的方法

在选择哪种方法来检查对象键是否存在时,我们需要考虑以下因素:

  • 性能: 如果性能是我们最关心的,则 in 操作符或 hasOwnProperty 方法通常是我们最佳选择,因为它们的复杂度为 O(1)。
  • 继承: 如果我们的需求是要区分继承或原型链上的属性,则 hasOwnProperty 方法是更好的选择。
  • falsy 值: 如果我们的需求是在 ES11 或更高版本的环境中使用简洁语法,并且不需要处理 falsy 值,则可选链或遍历所有键的方法更为合适。
  • JavaScript 版本: 如果我们的项目不支持 ES11,则不能使用可选链

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!