JavaScript短路求值错误?

3
以下两段JS代码让我感到困惑,因为在我看来,由于短路求值,两者应该是相同的。但是不知为何,在第一段代码中(第三行),会导致错误: Cannot read property 'match' of undefined 数组'a'保留了3个用户在输入框中输入的字符值。如果字符为未定义、空字符串、字母或数字,则希望代码返回true。
需要明确的是,当a = ['a', '/']时,这段代码会失败。
第一段代码如下:
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吧?

2个回答

4
答案很简单。看看运算顺序。 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]? - Ben Taliadoros
不,我的答案是a1为"typeof a[0] === 'undefined'",b1为"a[0] === ''"。 - Christoph

1

@Christoph是正确的,但你还需要在match后面添加类似于!== 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);

你可以查看这个fiddlehttp://jsfiddle.net/dv360q1p/1/,它实现了你的问题。

如果a [0]未定义,那么它不会评估a [0] .match(/ ^ [a-z0-9] + $ / i)!== null,对吗? - Ben Taliadoros
通常情况下不会。当您有多个或者遇到第一个为真的条件时,就没有必要继续评估其余表达式。同样地,对于与运算,当您得到第一个为假的条件时,可以停止。 - alphamikevictor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接