在Javascript中,为什么未定义对象的子键返回错误而不是未定义?

在Javascript中,为什么未定义对象的子键返回错误而不是未定义?,javascript,Javascript,假设我有一个当前未定义的对象 myObject.property1 这是有道理的,任何未定义内容的子项也应该评估为未定义,对吗 myObject.property1.description 但当我进入JS控制台时,我会: myObject.property1 未定义 myObject.property1.description TypeError:无法读取未定义的属性“说明” 如果我在做一个有条件的: if(myObject.property1.description){ console.l

假设我有一个当前未定义的对象

myObject.property1

这是有道理的,任何未定义内容的子项也应该评估为未定义,对吗

myObject.property1.description

但当我进入JS控制台时,我会:

myObject.property1

未定义

myObject.property1.description

TypeError:无法读取未定义的属性“说明”

如果我在做一个有条件的:

if(myObject.property1.description){
  console.log("it is defined!");
}else{
  console.log("it is not defined!");
}
我希望它可以控制台log
它没有定义但是我得到了错误,条件just flat out失败了。我希望它的计算结果是未定义的

  • 为什么它不返回
    未定义的
  • 我希望条件检查值的
    是否存在。我该怎么做
  • 为什么它不返回undefined呢

    因为这是特定的行为。一般来说,您希望在程序的早期捕获错误,而不是允许错误在程序中传播,并在程序的其他地方生成其他可能更严重的错误,而错误的原始来源可能很难确定。未定义的
    值通常是错误的征兆(或者至少是一些可能没有按预期工作的东西),需要尽早检查它们是一件非常好的事情。这意味着您需要在代码的早期编写防范
    未定义的
    值的措施,这些值会在代码中出现

    我希望条件检查值的存在。我该怎么做

    一个简单的解决方案如下所示:

    if(myObject && myObject.property1 && myObject.property1.description){
    
    if(myObject !== undefined && 
       myObject.property1 !== undefined && 
       myObject.property1.description !== undefined){
    
    var myObject = {
        property1: true
    };
    if ("property1" in myObject) {
        console.log("property1 is defined!");
        if (myObject.property1.hasOwnProperty("description")) {
            console.log("descrition is defined!");
        }else {console.log("descrition is not defined!");}
        }else {
            console.log(" none is defined!");
        }
    
    但当然,如果此链中的任何值为假,例如如果
    description
    为空字符串,则可能会产生意外结果。如果您确实只想查看该值是否未定义,可以执行以下操作:

    if(myObject && myObject.property1 && myObject.property1.description){
    
    if(myObject !== undefined && 
       myObject.property1 !== undefined && 
       myObject.property1.description !== undefined){
    
    var myObject = {
        property1: true
    };
    if ("property1" in myObject) {
        console.log("property1 is defined!");
        if (myObject.property1.hasOwnProperty("description")) {
            console.log("descrition is defined!");
        }else {console.log("descrition is not defined!");}
        }else {
            console.log(" none is defined!");
        }
    
    或者更详细一些,但更健壮一些:

    if(typeof myObject !== "undefined" && 
       typeof myObject.property1 !== "undefined" && 
       typeof myObject.property1.description !== "undefined"){
    

    有关详细讨论,请参阅。

    编程语言Groovy具有您想要的功能,它称之为“安全导航”操作符。语法是在需要此行为时使用
    ?。
    而不是
    。你会这么说吗

    if (myObject?.property1?.description) {
        // ...
    }
    
    if (isSet(myObject, 'property1.description')) {
        // ...
    }
    
    JavaScript似乎没有这样的功能,但它定义了一个函数,可以为您进行检查。要使用它,你会说

    if (myObject?.property1?.description) {
        // ...
    }
    
    if (isSet(myObject, 'property1.description')) {
        // ...
    }
    

    您可以先检查property1是否存在,然后检查是否有description属性,如下所示:

    if(myObject && myObject.property1 && myObject.property1.description){
    
    if(myObject !== undefined && 
       myObject.property1 !== undefined && 
       myObject.property1.description !== undefined){
    
    var myObject = {
        property1: true
    };
    if ("property1" in myObject) {
        console.log("property1 is defined!");
        if (myObject.property1.hasOwnProperty("description")) {
            console.log("descrition is defined!");
        }else {console.log("descrition is not defined!");}
        }else {
            console.log(" none is defined!");
        }
    

    为什么你不能先检查一下这个物体的存在?如果对象未定义,则返回undefined?这里有两个独立的问题,一个是要求我们阅读语言设计者的想法,另一个是询问如何解决特定问题。将你的问题缩小到其中一个(最好是主题一)。如果它不存在,它怎么可能有值?@Blunderfest,因为有时你只想检查某个特定值的存在,而不必担心根对象是否存在。。。如果根值不存在,那么检查是否存在子值也应该返回false。该链从左到右解析
    myObject.property1.description
    变为
    未定义。description
    ,并且
    未定义
    不是对象,因此不允许尝试访问其成员。谢谢。那你怎么去检查某个东西的存在呢?我明白了。对我来说,这听起来像是我刚刚发现了JS的一个缺点——我们应该能够检查对象子对象的存在,而不必首先检查父对象的存在(或者父对象的父对象,以及父对象的父对象,等等)。因为我们正在做你刚才做的疯狂的级联多重检查。如果(myObject.property1.description==exists)
    ,则最好使用类似于
    的东西,否?@fuzzybabybunny没有现成的方法。该语言的设计者希望您知道对象何时可能未定义,并对此加以防范,即使这意味着您有朝一日必须编写这样的代码。如果你真的想一想的话,另一种选择只会更糟糕。想象一下,如果在一个很长的函数之后,您发现了一个
    未定义的
    ,但是
    未定义的
    可能起源于代码中100个不同的位置中的任何一个。噢,哇,这一小段代码真的非常有用,工作得非常完美!它应该作为
    \u isSet
    或其他内容完全包含在下划线中。