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?

7
  • ^ The title is poorly worded for that question but if you read the accepted answer, it will explain this behavior. Commented Jun 7, 2016 at 17:36
  • @MikeC Nopes... Not a dupe of that / Wrong dupe target. :) Commented Jun 7, 2016 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. Commented Jun 7, 2016 at 17:40
  • order of operations Commented Jun 7, 2016 at 17:40
  • 1
    Possible duplicate of Concatenate string with ternary operator in javascript - the question is also being discussed on Meta. Commented Jun 9, 2016 at 14:06

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

7 Comments

To note - this is because of operator operator precedence - developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
@SergeS Thanks, but how does that come into play here. Will ? or === be considered as operator or what?
@PraveenKumar If you read that resource you'll see that + has higher precedence than ?: which in this case means that concatenation takes place before the ternary condition is evaluated.
@MikeC He he... Sorry. :P So ?: is also an operator. Thanks.
I will add that as a reason and correct my answer now.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.