30

I get unexpected result for this simple JavaScript assignment statement:

var t = 1 == 1 ? 1 : 0;
undefined

I would have expected to get 1 assigned to t instead. Same result if you do

var t = (1 == 1 ? 1 : 0);
undefined

Can somebody explain why this does not work as expected?

Gibin Ealias
  • 2,751
  • 5
  • 21
  • 39
faridz
  • 729
  • 1
  • 9
  • 9
  • 8
    Are you doing this in a console? If so, just type `t` after your assignment code to see the actual value that `t` has. I know that WebKit consoles behave like this. – Matt Ball Feb 22 '11 at 15:39
  • 1
    This has nothing to do with the operator, it has to deal with not understanding how the debugger works. – epascarello Feb 22 '11 at 16:12

4 Answers4

31

The result of evaluating var t = 1 == 1 ? 1 : 0; in, say, the Firebug console will be undefined. However, the value of t will be 1 as expected. Try outputting t after the assignment.

Firebug will print the result when the variable declaration is on a separate line:

var t;
t = 1 == 1 ? 1 : 0;

This is because the return value of an assignment operation is the value being assigned. However, when the var keyword is present, what's returning is the value of the VariableStatement declaration, which behaves as follows:

The production VariableStatement : var VariableDeclarationList; is evaluated as follows: Evaluate VariableDeclarationList. Return (normal, empty, empty).

Where Return (normal, empty, empty). refers to a type recognized by JavaScript internally, not something that would be printed to the console.

Further reading:

http://ecma262-5.com/ELS5_HTML.htm#Section_12.2

Wayne
  • 59,728
  • 15
  • 131
  • 126
17

It works perfectly:

> var t = 1 == 1 ? 1 : 0;
undefined
> t
1

You could say that the return value of the assignment operation is undefined, not the value of t.


Edit: But actually if I read the specification correctly, it seems that it should return the value of the expression.

As @T.J. Crowder mentioned, it seems the var is responsible for the undefined value. But that does not mean that you should not use var. The code you wrote is 100% correct.

This goes more into the inner workings of the language and I think that is not what you are interested in. Bur for more information about that, have a look at the comments.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 3
    Actually, the value of an *assignment operation* is the assigned value. The `var` keyword, however, gets in the way in consoles, apparently. (Since `var` can't appear on the right-hand side of an expression, that doesn't surprise me; seems a valid way to deal with the console aspect.) – T.J. Crowder Feb 22 '11 at 15:44
  • 1
    @TJCrowder: True, seems to be the `var`. Thanks for the insight. – Felix Kling Feb 22 '11 at 15:46
  • 2
    What happens is that the `var` statement returns a *normal completion* with no value, the *value of an assignment operation* is clearly the value of the assigned expression, e.g.: `var a; alert(a = 'foo'); alert(a);` will alert `'foo'` twice... Some time ago I was writing an article about the *completion type*, but I haven't time to finish it yet, here's an old [draft](http://j.mp/gI9IRv). – Christian C. Salvadó Feb 22 '11 at 15:49
  • @TJCrowder, @CMS: I just had a look at [this part of the specification](http://ecma262-5.com/ELS5_HTML.htm#Section_12.2) and there it is written that the evaluation returns `(normal, empty, empty)` so I guess this is what you mean by "normal completion" (which I could confirm after having a look at your draft). Thank you for that! – Felix Kling Feb 22 '11 at 15:53
  • @CMS: And once again I notice I should not talk so much about things I have no full insight ;) – Felix Kling Feb 22 '11 at 15:58
  • @CMS: I was just reading the spec and responding with a similar answer. It was clear to me that `Return (normal, empty, empty)` was referring to some internal return type, but I wasn't familiar with the terminology. Thanks for that. – Wayne Feb 22 '11 at 15:59
4

In old javascript parsers we need to conclude the condition in parentheses:

var t = (1 == 1) ? 1 : 0;
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
Andrei
  • 4,237
  • 3
  • 25
  • 31
  • 6
    I've been using JavaScript in browser implementations since 1996. I've never once seen one get the order of precedence wrong. Do you have a source for this? – T.J. Crowder Feb 22 '11 at 15:45
1

This code works fine:

var t = 1 == 1 ? 1 : 0;
alert (t);

Check here. It shows 1.

gor
  • 11,498
  • 5
  • 36
  • 42