【问题标题】:How are these two lines of code different that one throws an error and the other doesn’t?这两行代码有什么不同,一个抛出错误,另一个不抛出?
【发布时间】:2021-07-16 09:21:03
【问题描述】:

console.log("#1", "a12312a".match(/^\d+/)?.[0].length);
console.log("#2", ("a12312a".match(/^\d+/)?.[0]).length);

我正在编写一些代码,偶然发现了一些我不理解的东西。在 Chrome 89.0.4389.128 (Official Build) (64-bit) 中,上面的代码给出了这个:

#1 undefined
Uncaught TypeError: Cannot read property 'length' of undefined

这两行在我看来是一样的:"a12312a".match(/^\d+/)?.[0] 是一个undefined,他们正在尝试读取undefined 的属性length,它应该抛出一个TypeError。但是第一行没有,而第二行有。

……为什么?我糊涂了。我错过了一些非常基本的东西吗?

【问题讨论】:

    标签: javascript optional-chaining


    【解决方案1】:

    .match 返回 null,因为模式不匹配。所以比较是在

    null?.[0].length
    

    (null?.[0]).length
    

    这应该使过程更清晰。对于.?. 链,当它们从左到右求值时,如果在任何点左边的表达式是nullundefined,链将停在那里并且将整个事情评估为undefined

    但是,如果您通过将其中一个括在括号中来打破链,您只会在括号内得到一个简单的表达式:

    (undefined).length
    

    没有可选链的特殊机制。

    仅沿着属性访问和函数调用的连续序列的可选链接。介于两者之间的任何其他运算符(例如分组括号)都会破坏链。

    【讨论】:

    • 所以它影响整个链,而不仅仅是它的左右操作数,对吧?是不是说明customer?.details?.address?.citycustomer?.details.address.city是一样的?
    • 只有customer 可以为空。它们的不同之处在于,如果details 为null 而customer 存在,则在第二个版本中会抛出错误。
    • 你回答中的“在任何时候”部分让我有点困惑。不过,我了解操作员的工作方式。谢谢。
    猜你喜欢
    • 2021-11-17
    • 2016-05-27
    • 2015-11-01
    • 2012-11-25
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    相关资源
    最近更新 更多