Why does JavaScript variable declaration at console results in "undefined" being printed?
It prints the result of this expression - which is undefined
. And yes, var a
is a valid expression on its own.
Actually, you should rather be amused by why console
prints undefined
when you write var a = 3
or something like this. It also prints undefined
if function anyFunctionName() {}
statement is processed. In fact, all the var
and function
declaration (!) statements seem to be ignored if there's another statement with some 'real' result:
>>> var a = 3;
undefined
>>> var a = 3; a = 4;
4
>>> var a = 3; a = 4; var a = 5; function f() {};
4 // !!!
Now, I suppose the real reason behind is behaviour of eval
statement, as described here:
- Let
result
be the result of evaluating the programprog
.- If
result.type
isnormal
and its completion value is avalue V
, then return thevalue V
.- If
result.type
isnormal
and its completion value isempty
, then return the valueundefined
.
So now the question is, what does var a = 4
statement return? Guess what: it's not 4.
The production VariableStatement : var VariableDeclarationList; is evaluated as follows:
- Evaluate VariableDeclarationList.
- Return (normal, empty, empty).
Now the most interesting part: what happened in the last example, why 4 is the result? That's explained in this section:
The production Program : SourceElements is evaluated as follows:
- Let result be the result of evaluating SourceElements.
[...]
The production SourceElements : SourceElements *SourceElement* is evaluated as follows:
- Let headResult be the result of evaluating SourceElements.
- If headResult is an abrupt completion, return headResult.
- Let tailResult be result of evaluating SourceElement.
- If tailResult.value is empty, let V = headResult.value, otherwise let V = > tailResult.value.
- Return (tailResult.type, V, tailResult.target)
Both function f() {}
and var a = 5
statements' return values were (normal, empty, empty)
. So the script ended up with giving out the result of the first statement (starting from the script's end, so technically it's the last one) that's not (normal, empty, empty)
. That is the result of a = 4
assignment statement - which is 4
.
P.S. And now for some icing on the cake: consider the following:
>>> function f() {}
undefined
>>> (function f() {})
function f() {}
The difference is quite subtle: the first input is treated as a Function Declaration
statement, which, according to this rule...
The production SourceElement : FunctionDeclaration is evaluated as follows:
- Return (normal, empty, empty).
... will eventually produce undefined
when eval
-ed, as we already know.
The second input, however, is treated as a Function Expression
, which is evaluated to the function itself. That means it'll be passed through eval
and eventually returned to the console (in its format).
var a=1;
a
gives:
1
while
var a=1;
gives:
undefined
in the first case the console evaluates a so it prints the value of a
in the second case the console does not evaluate the value of a, but it evaluates the expression itself.
because all you are doing is declaring there is a variable - what is it? a string, an integer, a boolean - we don't know yet - hence undefined