0

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?

Arashsoft
  • 2,749
  • 5
  • 35
  • 58
  • ^ The title is poorly worded for that question but if you read the accepted answer, it will explain this behavior. – Mike Cluck Jun 07 '16 at 17:36
  • @MikeC Nopes... Not a dupe of that / Wrong dupe target. `:)` – Praveen Kumar Purushothaman Jun 07 '16 at 17:39
  • @PraveenKumar Like I said, it's not an exact dupe but the bug is the same. Ternary conditions are evaluated *after* concatenation which means that `undefinedVariable.toString()` is executed regardless of if `undefinedVariable === undefined`. – Mike Cluck Jun 07 '16 at 17:40
  • order of operations – epascarello Jun 07 '16 at 17:40
  • @MikeC Got it now man, thanks a lot. – Praveen Kumar Purushothaman Jun 07 '16 at 17:42
  • @MikeC, thank you for the help. The issue in your suggested dupe has the same solution. But, I do not think we can consider it as a duplicate. – Arashsoft Jun 07 '16 at 17:56
  • 1
    Possible duplicate of [Concatenate string with ternary operator in javascript](http://stackoverflow.com/questions/29444009/concatenate-string-with-ternary-operator-in-javascript) - the question is also being discussed on [Meta](http://meta.stackoverflow.com/questions/325854/using-duplicate-report-to-increase-the-answer-votes-what-should-we-do). – Glorfindel Jun 09 '16 at 14:06

1 Answers1

3

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

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252