Each time you evaluate a line of code, you get a completion type/record result
which has 3 attributes: type
, value
and target
. According to the Ecma specification:
If result.type
is normal and its completion value is a value V
, then return the value V
.
If result.type
is normal and its completion value is empty
, then return the value undefined
.
It turns out that when you declare a variable or a function, the completion type
is (normal,empty,empty)
. Since the result.type
is normal
and value is empty
, it returns the value undefined
.
However when you type a = 3
, it's an assignment expression and its completion type is (normal, GetValue(), empty)
. So you will just see 3
in the console.
For terms around statement
and expression
, see difference statement/expression.
For different values of completion type, see completion type documentation.
If you check the completion type documentation, you can see that empty statement ;
has also a completion type (normal, empty, empty)
(so it should return undefined
), and indeed it's the case. For the same reason, if (x>3) {console.log(x)}
also returns undefined
and do {console.log(3);} while (false)
too.
However, (function f(){})
doesn't return undefined
because it's an expression statement.
Test by yourself. Here are some more examples:
eval('function f(){}'); // Return (normal, empty, empty), undefined
eval(';'); // Return (normal, empty, empty), undefined
eval('(function f(){})'); // (normal, GetValue(exprRef), empty), ExpresionStatement
function foo() {
return 4;
} // Return (normal, empty, empty), undefined
foo(); // (return, 4, empty), 4
eval('function foo() {return 5;}'); // Return (normal, empty, empty), undefined
eval('foo();'); // (return, 4, empty), 4
let x = 4; // (normal, empty, empty), undefined
if (x > 3) {
console.log(x);
} // (normal, empty, empty), undefined
console.log(6); // (normal, empty, empty), undefined
eval('let x = 4; if (x>3) {console.log(x)}'); // undefined
let y = 5; // (normal, empty, empty), undefined
do {
console.log(3);
y++;
} while (y < 8); // this returns y, can you explain why?
do {
console.log(3);
} while (false); // undefined since (normal, empty, empty)