检查未知对象中的对象是不是存在的最有效的Javascript方法[重复]

Posted

技术标签:

【中文标题】检查未知对象中的对象是不是存在的最有效的Javascript方法[重复]【英文标题】:Most efficient Javascript way to check if an object within an unknown object exists [duplicate]检查未知对象中的对象是否存在的最有效的Javascript方法[重复] 【发布时间】:2015-11-09 15:02:37 【问题描述】:

这是我在 javascript 中经常遇到的问题。假设我有一个这样的对象:

var acquaintances = 
   types: 
      friends: 
         billy: 6,
         jascinta: 44,
         john: 91
         others: ["Matt", "Phil", "Jenny", "Anna"]
      ,
      coworkers: 
         matt: 1
      
   

在我的理论程序中,我只知道acquaintances 是一个对象;我不知道是否设置了acquaintances.types,或者其中是否设置了friends

如何高效检查acquaintances.types.friends.others是否存在?

我通常会做的是:

if(acquaintances.types)
  if(aquaintances.types.friends)
    if(acquaintances.types.friends.others)
       // do stuff with the "others" array here
     
  

除了费力之外,这些嵌套的if 语句管理起来有点像噩梦(实际上我的对象的级别远不止于此!)。但是如果我直接尝试if(acquaintances.types.friends.others)) 之类的东西,而types 还没有设置,那么程序就会崩溃。

Javascript 有哪些方法可以简洁、易于管理?

【问题讨论】:

CoffeeScript 有一个符合您描述的? 运算符,请参阅here。不知道纯 JS 中的简单技巧。 顺便说一句,就执行时间而言,它并不是高效 【参考方案1】:

另一种方法是:

((acquaintances.types || ).friends || ).others

它比其他解决方案更短,但可能会或可能不会让您兴奋。

您还可以构建一个小帮手,让同样的想法更受欢迎:

function maybe(o)  return o || ; 

现在你可以做

maybe(maybe(acquaintances.types).friends).others

如果你不介意将属性名写成字符串,你可以做一个小帮手:

function maybe(obj) 
  return Object.defineProperty(
    obj || , 
    'get', 
     value: function(prop)  return maybe(obj[prop]); 
  );

现在你可以写了

maybe(acquaintances.types').get('friends').others

在 ES6 中,您可以使用带默认值的解构赋值来做到这一点,虽然很笨拙:

var  types:  friends:  others  =   =   = acquaintances;

如果您想在表达式上下文中使用 this,而不是分配给变量,理论上您可以使用参数解构:

(( types:  friends:  others  =   =  ) => others)(acquaintances)

说到底,还是标准的做法

acquaintances.types && 
  acquaintances.types.friends && 
  acquaintances.types.friends.others

这就是为什么在 ES6 设计小组中有一个活跃的 (?) discussion 关于类似 CoffeeScript 的存在运算符,但它似乎并没有很快收敛。

【讨论】:

【参考方案2】:

这在 JavaScript 中不好。

您可以将它们添加到一个大条件...

if (obj.prop && obj.prop.someOtherProp)  

...或者编写一个辅助函数来传递一个对象和一个字符串...

var isPropSet = function(object, propPath) 
    return !! propPath.split('.')
           .reduce(function(object, prop)  return object[prop] || ; , object);
;

isPropSet(obj, 'prop.someOtherProp);

...或者您可以使用 CoffeeScript 及其 ? 运算符...

obj.prop?.someOtherProp

您也可以将查找包装在try/catch 中,但我不推荐它。

【讨论】:

我觉得你需要return object[prop] || ;;否则像isPropSet(obj, 'prop.foo.bar') 这样的调用会产生运行时错误。 @torazaburo 是的,你是对的,它不应该在测试属性时爆炸。【参考方案3】:

而不是这个:

if(acquaintances.types)
  if(aquaintances.types.friends)
    if(acquaintances.types.friends.others)
       // do stuff with the "others" array here
     
  

试试这个:

   if(acquaintances &&
      acquaintances.types &&
      acquaintances.types.friends &&
      acquaintances.types.friends.others) 
    

或者

acquaintances &&
acquaintances.types &&
acquaintances.types.friends &&
acquaintances.types.friends.others ?
doSomething() : doSomethingElse()

【讨论】:

【参考方案4】:

and 运算符是连续的,因此您可以在不嵌套 if 语句的情况下执行此操作。

if(acquaintances.types && aquaintances.types.friends && acquaintances.types.friends.others)
    //acquaintances.types.friends.others exists!

【讨论】:

以上是关于检查未知对象中的对象是不是存在的最有效的Javascript方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章

检查 JavaScript 中是不是存在深度嵌套对象属性的最简单方法是啥? [复制]

检查表中是不是存在行的最有效方法是啥?

检查对象中是不是存在键[重复]

在 SQL Server 中检查逗号分隔字符串中是不是存在子字符串的最有效方法

检查数组是不是包含Java中的值的最有效方法? [复制]

有效地检查 Python / numpy / pandas 中的任意对象是不是为 NaN?