【问题标题】:Shorter way to do: if (a !== undefined && a.b !== undefined && a.b.c === 'foo')更短的方法: if (a !== undefined && a.b !== undefined && a.b.c === 'foo')
【发布时间】:2017-05-22 19:05:01
【问题描述】:

如果我需要检查一个对象的属性,它是对象(等等),但不能确定该对象是否存在,我怎样才能使条件比这更简单?

if (a !== undefined && a.b !== undefined && a.b.c === 'foo')

如果有任何有意义的功能,我也会使用 LoDash

【问题讨论】:

  • a 不存在时,该代码将引发错误。请参阅下面的答案以获取正确的代码。

标签: javascript object lodash


【解决方案1】:

如果您知道 a 在当前范围内(例如作为参数传入),您可以这样做
if(a && a.b && a.b.c === 'foo')
但是如果有机会 a从未定义过,您必须检查以下类型:
if( typeof a != 'undefined' && a.b && a.b.c === 'foo')

更新
使用 lodah 时,has 函数可以提供更好的语法(与 get 函数不同,如果属性是假值,则返回 true。感谢 @ryeballar): if(lodash.has(a,'b.c')){ console.log(a.b.c); }

【讨论】:

  • if(a && a.b && a.b.c === 'foo')a 不存在时会抛出错误。
  • @ScottMarcus:如果a 不存在,那么无论如何都应该解决这个错误,从而使错误消息变得很重要。如果a 是一个无法知道的全局变量,那么window.a && a.b && a.b.c
  • @ScottMarcus 你是对的!我更新了我的答案。感谢您了解它
  • @VeXii:我们不要随便掩埋我们的错误。如果您正在读取一个不存在的变量,那么问题应该是固定的,而不是隐藏的。 typeof a !== "undefined" 语法可能导致比它解决的问题更多的问题,从模糊的错误和简单的拼写错误导致语法错误。
  • @VeXii lodash#get 如果来自对象路径的值是假值,则可能返回假。您可以改用lodash#has
【解决方案2】:

Lodash 有_.get,它允许您定义指向对象中嵌套项的键路径。它会为您处理中间检查,如果未找到密钥,则仅返回 undefined 或默认值。

if(_.get(a, 'b.c') === 'foo')

【讨论】:

    【解决方案3】:

    如果a 真的不存在,你会想要一个try/catch,这意味着你可以这样做:

    try {
        if (a.b.c === 'foo') {
            // Do stuff.
        }
    } catch (ignore) {}
    

    【讨论】:

    • 这将捕获来自ab 的错误,而无法知道是哪种情况。这可以通过使用typeof 来避免。此外,这并不比 OP 已经提出的要短,这正是问题所要求的。
    • @ScottMarcus: typeof a !== "undefined" && a.b && a.b.c === 'foo' 也不会告诉您是未定义的 a 还是 a.b。那又怎样……
    • @squint 是的,但如果你分解测试它可以。
    • @ScottMarcus,从技术上讲,删除评论后它缩短了六个字符,但谁在数呢?
    • 是的,是的。我想我在想更多的代码行。 ;)
    【解决方案4】:

    在你担心让你的代码更短之前,你需要知道当a不存在时你的代码会抛出一个错误:

    if (a !== undefined && a.b !== undefined && a.b.c === 'foo'){
      console.log("a exists, a.b exists and a.b.c === 'foo'");
    }

    您无法访问不存在的对象而不会出错。因此,您需要检查atype 是否不是"undefined"(注意,要检查的值是字符串)。

    function checkObj(){
      if (typeof a !== "undefined" && a.b && a.b.c === 'foo'){
        console.log("a exists, a has a b property and a.b.c === 'foo'");
      } else {
        console.log("Not all conditions met.");
      }
    }
    
    checkObj();  // a doesn't exist --> "Not all conditions met."
    
    var a = {};
    
    checkObj(); // a exists, but b and c don't --> "Not all conditions met."
    
    a.b = {};
    
    checkObj();  // a and b exist but c doesn't --> "Not all conditions met."
    
    a.b.c = "test";
    
    checkObj();  // a, b and c exist, but c has wrong value --> "Not all conditions met."
    
    a.b.c = "foo";
    
    checkObj();  // "a exists, a has a b property and a.b.c === 'foo'"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 1970-01-01
      • 2021-05-19
      相关资源
      最近更新 更多