表达语句
表达式语句是在需要语句的地方使用的表达式。该表达式将被求值,其结果将被丢弃 - 因此,它仅对于具有副作用的表达式才有意义,例如执行函数或更新变量。
¥An expression statement is an expression used in a place where a statement is expected. The expression is evaluated and its result is discarded — therefore, it makes sense only for expressions that have side effects, such as executing a function or updating a variable.
语法
描述
¥Description
除了 专用语句语法 之外,你还可以使用几乎任何 expression 作为单独的语句。表达式语句语法要求末尾有一个分号,但如果缺少分号导致语法无效,自动插入分号 进程可能会为你插入一个分号。
¥Apart from the dedicated statement syntaxes, you can also use almost any expression as a statement on its own. The expression statement syntax requires a semicolon at the end, but the automatic semicolon insertion process may insert one for you if the lack of a semicolon results in invalid syntax.
由于表达式先被求值然后被丢弃,所以表达式的结果不可用。因此,该表达式必须具有一些副作用才能有用。表达式语句通常有:
¥Because the expression is evaluated and then discarded, the result of the expression is not available. Therefore, the expression must have some side effect for it to be useful. Expression statements are commonly:
- 函数调用(
console.log("Hello");
、[1, 2, 3].forEach((i) => console.log(i));
) - 标记模板文字
- 赋值表达式,包括复合作业
- 自增和自减运算符
delete
import()
yield
和yield*
其他人如果调用 getters 或触发 类型强制 也可能会产生副作用。
¥Others may also have side effects if they invoke getters or trigger type coercions.
禁止表达
¥Forbidden expressions
为了将表达式用作语句,它不能与其他语句语法产生歧义。因此,表达式不得以以下任何标记开头:
¥In order for an expression to be used as a statement, it must not be ambiguous with other statement syntaxes. Therefore, the expression must not start with any of the following tokens:
function
:这将是function
声明 或function*
声明,而不是function
表达 或function*
表达async function
:这将是async function
声明 或async function*
声明,而不是async function
表达 或async function*
表达class
:这将是class
声明,而不是class
表达let[
:这将是let
声明 和 数组解构,而不是let
变量上的 属性访问器(let
只能是 非严格模式 中的标识符){
:这将是 块语句,而不是 对象字面量
因此,以下所有内容均无效:
¥Therefore, all of the following are invalid:
function foo() {
console.log("foo");
}(); // SyntaxError: Unexpected token '('
// For some reason, you have a variable called `let`
var let = [1, 2, 3];
let[0] = 4; // SyntaxError: Invalid destructuring assignment target
{
foo: 1,
bar: 2, // SyntaxError: Unexpected token ':'
};
更危险的是,有时代码恰好是有效的语法,但不是你想要的。
¥More dangerously, sometimes the code happens to be valid syntax, but is not what you intend.
// For some reason, you have a variable called `let`
var let = [1, 2, 3];
function setIndex(index, value) {
if (index >= 0) {
// Intend to assign to the array `let`, but instead creates an extra variable!
let[index] = value;
}
}
setIndex(0, [1, 2]);
console.log(let); // [1, 2, 3]
// This is not an object literal, but a block statement,
// where `foo` is a label and `1` is an expression statement.
// This often happens in the console
{ foo: 1 };
为了避免这些问题,可以使用括号,使该语句明确是表达式语句。
¥To avoid these problems, you can use parentheses, so that the statement is unambiguously an expression statement.
(function foo() {
console.log("foo");
})();
示例
避免控制流语句
¥Avoiding control flow statements
你可以使用表达式语句来避免几乎所有控制流语句的使用。例如,if...else
可以替换为 三元运算符 和 逻辑运算符。诸如 for
或 for...of
之类的迭代语句可以用 数组方法 替换。
¥You can avoid almost all use of control flow statements using expression statements. For example, if...else
can be replaced with ternary operators and logical operators. Iterative statements like for
or for...of
can be replaced with array methods.
// Using control flow statements
function range(start, end) {
if (start > end) {
[start, end] = [end, start];
}
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
}
// Using expression statements
function range2(start, end) {
start > end && ([start, end] = [end, start]);
return Array.from({ length: end - start }, (_, i) => start + i);
}
警告:这仅展示了该语言的能力。过度使用表达式语句来代替控制流语句可能会降低代码的可读性。
¥Warning: This only demonstrates a capability of the language. Excessive use of expression statements as a substitute for control-flow statements can make code much less readable.
规范
Specification |
---|
ECMAScript Language Specification # sec-expression-statement |