#24js 中的语句 & 表达式 & 分号
- 语句是一段可以执行并执行某种操作的代码
- 表达式是一段代码,可以对其进行求值以产生一个值
- 表达式可以用作语句,被称为表达式语句。反之则不然:当上下文需要表达式时,不能使用语句
- 每条语句都以分号结尾
- 以块结尾的语句
function foo() { // ... } if (x > 0) { // ... }
- 控制语句的主体本身就是一个语句
while (condition) statement
// 表达式 `bar()` 可以是表达式或语句——这取决于上下文
function foo() {
console.log(bar()) // bar() 是表达式
bar(); // bar(); 是表达式语句
}
// 函数声明
function foo(x) {
return x;
}
// 函数表达式(=右侧)
const fooo = function bar(x) {
return x;
}
// 对象字面量
const obj = {};
// 空代码块
{
}
// 整个 const 声明(一个语句)以分号结尾,但在它里面,有一个箭头函数表达式。
// 也就是说,它本身并不是以花括号结尾的语句;
// 它是嵌入的箭头函数表达式。 这就是为什么末尾有一个分号。
const foo = () => {};
消除歧异
歧义只是语句上下文中的问题:如果 JavaScript 解析器遇到歧义语法,它不知道它是普通语句还是表达式语句。 例如:
- 如果语句以函数开头:它是函数声明还是函数表达式?
- 如果语句以
{
开头:它是对象字面量还是代码块?
为了解决歧义,以 function
或 {
开头的语句永远不会被解释为表达式。如果希望表达式语句以这些标记之一开头,则必须将其括在括号中。
// -------- (a) 创建函数 -------- | (b) 调用函数
(function (x) { console.log(x) })('abc');
// (a) 中的代码片段被解释为表达式,因为将其包裹在括号中。
// 如果不这样做,会得到一个语法错误,因为 JavaScript 需要一个函数声明并抱怨缺少函数名。
// 此外,不能在函数声明之后立即进行函数调用。
// Uncaught SyntaxError: Function statements require a function name
自动插入分号
Automatic semicolon insertion (ASI)
ASI 的工作原理如下。语句的解析继续进行,直到出现以下任一情况:
- 分号
- 行终止符后跟非法标记
换句话说,ASI 可以看作是在换行符处插入分号。
return
{
name: 'lencx'
};
// 解析后
return;
{
name: 'lencx';
}
;
// 1. 不带操作数的返回语句:return;
// 2. 代码块的开始:{
// 3. 表达式语句 'lencx',标签 name
// 4. 代码块结束:}
// 5. 空语句:;
// 为什么 JavaScript 会这样做? 它可以防止在返回后意外返回一行中的值。