JavaScript 短路评估错误?

Posted

技术标签:

【中文标题】JavaScript 短路评估错误?【英文标题】:JavaScript short circuit evaluation error? 【发布时间】:2015-05-11 20:55:38 【问题描述】:

下面两个 JS 代码的 sn-ps 让我感到困惑,在我看来,由于短路评估,两者应该工作相同。但由于某种原因 sn -p '1' 导致错误(在第三行):

无法读取未定义的属性“匹配”

数组“a”包含用户输入的 3 个字符值。如果 char 未定义、空字符串、字母或数字,我希望代码返回 true。

需要明确的是,当 a = ['a', '/']; 时这会失败

片段 1)

return typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i) 
    && typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i) 
    && typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i);

片段 2)

if (typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i)) 
    if (typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i)) 
        if (typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i)) 
            return true;           
        
        return false;
    
    return false;

return false;

如果由于 'if' 中的第一个条件而导致 a[2] 未定义,那么肯定永远不应评估 a[2].match 吗?

【问题讨论】:

【参考方案1】:

答案很简单。看看order of operations。 AND 比 OR 绑定更多。

在您的代码段 1 中,表达式如下:

a1 || b1 || (c1 && a2) || b2 || (c2 && a3) || b3 || c3

你的片段 2 是这样的:

(a1 || b1 || c1) && (a2 || b2 || c2) && (a3 || b3 || c3)

【讨论】:

你的答案是 a1 == a[0]?和 b1 == a[1]? 不,在我看来 a1 是“typeof a[0] === 'undefined'” 而 b1 是“a[0] === ''”【参考方案2】:

@Christoph 是对的,但您还需要在匹配之后添加类似 !== null 的内容

return (typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i) !==null )  && (typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i) !== null ) && (typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i) !== null);

你可以看看这个实现你的问题的小提琴http://jsfiddle.net/dv360q1p/1/

【讨论】:

如果 a[0] 未定义,它肯定不会计算 a[0].match(/^[a-z0-9]+$/i) !==null 对吗?跨度> 通常不会。当您遇到多个 OR 时,当您遇到第一个真条件时,无需继续评估其余的表达式。以及当你得到第一个 false 时你可以停止。

以上是关于JavaScript 短路评估错误?的主要内容,如果未能解决你的问题,请参考以下文章

线性搜索和短路评估(运行时错误)

单线逻辑或短路评估的 AHK 等效项是啥?

你能防止 Lua 中的短路评估吗?

短路评估VS 2017 c++

当运算符优先级说不应该时,为啥短路评估会起作用?

当短路评估可能导致函数未被调用时,是不是有 gcc 警告标志?