Chapter 5: Grammar
Statements & Expressions
var a = 3 * 6;
var b = a;
b;
In this snippet, 3 * 6
is an expression (evaluates to the value 18
). But a
on the second line is also an expression, as is b
on the third line. The a
and b
expressions both evaluate to the values stored in those variables at that moment, which also happens to be 18
.
Moreover, each of the three lines is a statement containing expressions. var a = 3 * 6
and var b = a
are called “declaration statements” because they each declare a variable (and optionally assign a value to it). The a = 3 * 6
and b = a
assignments (minus the var
s) are called assignment expressions.
The third line contains just the expression b
, but it’s also a statement all by itself (though not a terribly interesting one!). This is generally referred to as an “expression statement.”
“声明”和“表达式”的概念在几乎任何语言都是通用的。
It’s a fairly little known fact that statements all have completion values (even if that value is just undefined
).
Let’s consider var b = a
. What’s the completion value of that statement?
The b = a
assignment expression results in the value that was assigned (18
above), but the var
statement itself results in undefined
. Why? Because var
statements are defined that way in the spec.
The general idea is to be able to treat statements as expressions – they can show up inside other statements – without needing to wrap them in an inline function expression and perform an explicit return ..
.
For now, statement completion values are not much more than trivia.
这个设计我感觉是有点多余的,如果仅仅是为了省掉一行return语句的话
Note: Would you think ++a++
was legal syntax? If you try it, you’ll get a ReferenceError
error, but why? Because side-effecting operators require a variable reference to target their side effects to. For ++a++
, the a++
part is evaluated first (because of operator precedence – see below), which gives back the value of a
before the increment. But then it tries to evaluate ++42
, which (if you try it) gives the same ReferenceError
error, since ++
can’t have a side effect directly on a value like 42
.
这波解释很精妙。
This behavior that an assignment expression (or statement) results in the assigned value is primarily useful for chained assignments, such as:
var a, b, c;
a = b = c = 42;
Here, c = 42
is evaluated to 42
(with the side effect of assigning 42
to c
), then b = 42
is evaluated to 42
(with the side effect of assigning 42
to b
), and finally a = 42
is evaluated (with the side effect of assigning 42
to a
).
这里之所以可以连续赋值,正是因为c=42
除了赋值这个操作外还会将所赋的值返回出来。