Search code examples
javascriptjavascript-engine

Unable to correctly write ternary operator in JavaScript


I have an undefined variable and I check it in a string concat:

var undefinedVariable = undefined;
console.log("foo" + undefinedVariable === undefined ? "bar" : undefinedVariable.toString() );

Considering that undefinedVariable is undefined, undefinedVariable.toString() is an unreachable code. However, I get this error:

Uncaught TypeError: Cannot read property 'toString' of undefined(…)

The strange thing is if I remove "foo" at the start of console.log, then the code works fine.

console.log(undefinedVariable === undefined ? "bar" : undefinedVariable.toString() );

I have tested in chrome and firefox and I get the same result so probably it is not a bug. Is there any explanation why JS engines try to run the unreachable part?


Solution

  • It is because of the Operator Precedence. The + (concatenation operator) has a greater precedence than the ?: (ternary operator). So, you need to enclose the ternary condition inside () because, it takes it along with the + (concatenation operator) and no more the left side is undefined. Use:

    console.log("foo" + (undefinedVariable === undefined ? "bar" : undefinedVariable.toString()) );
    

    You need to tell the JavaScript engine to evaluate the undefinedVariable separately and don't join both the "foo" and undefinedVariable and evaluate.

    var undefinedVariable = undefined;
    console.log("foo" + (undefinedVariable === undefined ? "bar" : undefinedVariable.toString()) );

    The above gives me: foobar.

    Output