#24js 中的语句 & 表达式 & 分号

lencxlencx2022/03/30
  • 语句是一段可以执行并执行某种操作的代码
  • 表达式是一段代码,可以对其进行求值以产生一个值
  • 表达式可以用作语句,被称为表达式语句。反之则不然:当上下文需要表达式时,不能使用语句
  • 每条语句都以分号结尾
  • 以块结尾的语句
    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 会这样做? 它可以防止在返回后意外返回一行中的值。

License Copyright © 2022-present lencx