Search code examples
javascriptconditional-statementsconditional-operatortypeofshort-circuiting

JavaScript short circuit evaluation error?


The two below snippets of JS code have had me confused, in my eyes both should work the same, due to short circuit evaluation. But for some reason snippet '1' causes the error (on the third line):

Cannot read property 'match' of undefined

Array 'a' holds 3 character values user entered into inputs. I want the code to return true if the char is undefined, an empty string, or a letter or number.

To be clear, this fails when a = ['a', '/'];

Snippet 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);

Snippet 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;

Surely a[2].match should never be evaluated if a[2] is undefined due to the first conditional in the 'if'?


Solution

  • The answer is simple. Take a look to the order of operations . AND binds more than OR.

    In your Snippet 1 the expression is like:

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

    Your Snippet 2 is like:

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