6.语法

原文: http://exploringjs.com/impatient-js/ch_syntax.html

6.1。 JavaScript 语法概述

6.1.1。基本语法

评论:

原始 (原子)值:

断言 描述了计算结果的预期结果,如果这些期望不正确则抛出异常。例如,以下断言声明计算 7 加 1 的结果必须为 8:

assert.equal()是一个方法调用(对象是assert,方法是.equal()),有两个参数:实际结果和预期结果。它是 Node.js 断言 API 的一部分,本书后面的将对此进行解释

登录到浏览器的控制台或 Node.js:

运算符:

声明变量:

控制流声明:

普通函数声明:

箭头函数表达式(特别用作函数调用和方法调用的参数):

前面的代码包含以下箭头函数(术语 表达式 语句 在本章后面解释):

对象:

数组(数组也是对象):

6.1.2。模块

每个模块都是一个文件。例如,考虑以下两个包含模块的文件:

  1. file-tools.js
  2. main.js

file-tools.js中的模块导出其功能isTextFilePath()

main.js中的模块导入整个模块path和函数isTextFilePath()

6.1.3。法定变量和属性名称

变量名称和属性名称的语法类别称为 标识符

标识符允许具有以下字符:

  • Unicode 字母:A - Za - z(等)
  • $_
  • Unicode 数字:0 - 9(等)
    • 变量名不能以数字开头

有些单词在 JavaScript 中有特殊含义,称为 reserved 。例子包括:iftrueconst

保留字不能用作变量名:

但它们被允许作为属性的名称:

6.1.4。套管款式

用于连接单词的常见套管样式是:

  • 骆驼案:threeConcatenatedWords
  • 下划线案例(也称 蛇案 ):three_concatenated_words
  • Dash 案例(也称 kebab 案例 ):three-concatenated-words

6.1.5。名字的大写

通常,JavaScript 使用驼峰大小写,但常量除外。

小写:

  • 功能,变量:myFunction
  • 方法:obj.myMethod
  • CSS:
    • CSS 实体:special-class
    • 对应的 JavaScript 变量:specialClass

大写:

  • 职业:MyClass
  • 常数:MY_CONSTANT
    • 常量也常用骆驼写成:myConstant

6.1.6。在哪里加分号?

在声明的最后:

但是,如果该声明以大括号结尾,那就不是了:

但是,在这样的语句之后添加分号不是语法错误 - 它被解释为空语句:

6.语法 - 图1 测验:基本

参见测验应用程序

6.2。 (高级)

本章的所有其余部分都是高级的。

6.3。身份标识

6.3.1。有效标识符(变量名等)

第一个字符:

  • Unicode 字母(包括éü等重音字符和非拉丁字母的字符,如α
  • $
  • _

后续人物:

  • 法律第一个字符
  • Unicode 数字(包括东方阿拉伯数字)
  • 一些其他 Unicode 标记和标点符号

例子:

6.3.2。保留字

保留字不能是变量名,但它们可以是属性名。

所有 JavaScript 关键字 都是保留字:

await break case catch class const continue debugger default delete do else export extends finally for function if import in instanceof let new return static super switch this throw try typeof var void while with yield

以下标记也是关键字,但目前未在该语言中使用:

enum implements package protected interface private public

以下字面值是保留字:

true false null

从技术上讲,这些单词不是保留的,但你也应该避免使用它们,因为它们实际上是关键字:

Infinity NaN undefined async

您也不应将全局变量的名称(StringMath等)用于您自己的变量和参数。

6.4。语句与表达

在本节中,我们将探讨 JavaScript 如何区分两种句法结构: 语句 表达式 。之后,我们会发现这会导致问题,因为相同的语法可能意味着不同的东西,具体取决于它的使用位置。

6.语法 - 图2 我们假装只有语句和表达

为简单起见,我们假装 JavaScript 中只有语句和表达式。

6.4.1。声明

语句 是一段可以执行并执行某种操作的代码。例如,if是一个声明:

声明的另一个例子:函数声明。

6.4.2。表达式

表达式 是可以 评估 以产生值的一段代码。例如,括号之间的代码是一个表达式:

括号之间使用的运算符_?_:_称为 三元运算符 。它是if语句的表达式版本。

让我们看一下表达式的更多例子。我们输入表达式,REPL 为我们评估它们:

6.4.3。什么是允许的?

JavaScript 源代码中的当前位置决定了您可以使用哪种语法结构:

  • 函数体必须是一系列语句:

  • 函数调用或方法调用的参数必须是表达式:

但是,表达式可以用作语句。然后将它们称为 表达式语句 。相反的情况并非如此:当上下文需要表达式时,您不能使用语句。

以下代码演示了任何表达式bar()可以是表达式还是语句 - 它取决于上下文:

6.5。语法模糊

JavaScript 有几种语法歧义的编程结构:相同的语法被不同地解释,这取决于它是在语句上下文中还是在表达式上下文中使用。本节探讨了这一现象及其引发的陷阱。

6.5.1。相同的语法:函数声明和函数表达式

函数声明 是一个声明:

函数表达式 是表达式(=的右侧):

6.5.2。相同的语法:object literal 和 block

在下面的代码中,{} 对象字面值 :一个创建空对象的表达式。

这是一个空代码块(声明):

6.5.3。消歧

歧义只是语句上下文中的一个问题:如果 JavaScript 解析器遇到模糊语法,它不知道它是简单语句还是表达式语句。例如:

  • 如果语句以function开头:它是函数声明还是函数表达式?
  • 如果语句以{开头:它是对象字面值还是代码块?

为了解决歧义,以function{开头的语句永远不会被解释为表达式。如果希望表达式语句以这些标记中的任何一个开头,则必须将其包装在括号中:

在这段代码中:

  1. 我们首先通过函数表达式创建一个函数:

  2. 然后我们调用该函数:('abc')

#1 只被解释为表达式,因为我们将它包装在括号中。如果我们没有,我们会得到一个语法错误,因为然后 JavaScript 需要一个函数声明并抱怨缺少的函数名称。此外,您不能在函数声明后立即进行函数调用。

在本书的后面,我们将看到更多由语法模糊引起的陷阱的例子:

6.6。分号

6.6.1。分号的经验法则

每个语句都以分号结束。

除外:以块结尾的语句。

以下情况有点棘手:

整个const声明(一个语句)以分号结尾,但在其中,有一个箭头函数表达式。那就是:声明本身并不是以花括号结尾;它是嵌入式箭头函数表达式。这就是为什么最后会有一个分号的原因。

6.6.2。分号:控制语句

控制语句的主体本身就是一个声明。例如,这是while循环的语法:

正文可以是一个声明:

但是块也是声明,因此是控制声明的法律机构:

如果你想让一个循环有一个空体,你的第一个选项是一个空语句(它只是一个分号):

你的第二个选择是一个空块:

6.7。自动分号插入(ASI)

虽然我建议总是写分号,但大多数都是 JavaScript 中的可选项。使这成为可能的机制称为 自动分号插入 (ASI)。在某种程度上,它可以纠正语法错误。

ASI 的工作原理如下。解析声明会持续到以下任何一个:

  • 分号
  • 行终止符后跟非法标记

换句话说,ASI 可以看作在换行符处插入分号。接下来的小节将介绍 ASI 的陷阱。

6.7.1。 ASI 意外触发

关于 ASI 的好消息是 - 如果你不依赖它并且总是写分号 - 你只需要注意一个陷阱。这是 JavaScript 禁止在一些标记之后的换行符。如果插入换行符,也会插入分号。

最实际相关的标记是return。例如,考虑以下代码:

此代码解析为:

也就是说,一个空的 return 语句,后跟一个代码块,后跟一个空语句。

为什么 JavaScript 会这样做?它可以防止在return之后意外返回一行中的值。

6.7.2。 ASI 意外没有触发

在某些情况下,当您认为应该是 ASI 时,ASI 是 而不是 。对于那些不喜欢分号的人来说,这会使生活更加复杂,因为他们需要了解这些案例。以下是三个例子。还有更多。

例 1:非预期的函数调用。

解析为:

例 2:意外分裂。

解析为:

例 3:非预期的财产访问。

执行:

6.8。分号:最佳实践

我建议你总是写分号:

  • 我喜欢它提供代码的视觉结构 - 你清楚地看到一个语句何时结束。
  • 要记住的规则较少。
  • 大多数 JavaScript 程序员使用分号。

然而,也有许多人不喜欢添加分号的视觉混乱。如果您是其中之一:没有它们的代码 合法的。我建议您使用工具来帮助您避免错误。以下是两个例子:

  • 自动代码格式化程序 Prettier 可以配置为不使用分号。然后它会自动修复问题。例如,如果它遇到以方括号开头的行,则它以分号为前缀。
  • 静态检查器 ESLint 具有规则,您可以告诉您的首选样式(始终使用分号或尽可能少的分号),并警告您关键问题。

6.9。严格的模式

从 ECMAScript 5 开始,您可以选择在所谓的 严格模式 中执行 JavaScript。在该模式下,语言稍微清晰:不存在一些怪癖并且抛出更多异常。

默认(非严格)模式也称为 草率模式

请注意,默认模式在模块和类中默认打开,因此在编写现代 JavaScript(几乎总是位于模块中)时,您并不需要了解它。在本书中,我假设严格模式始终打开。

6.9.1。开启严格模式

在旧脚本文件和 CommonJS 模块中,通过将以下代码放在第一行中,您可以为完整文件切换严格模式:

关于这个“指令”的巧妙之处在于,5 之前的 ECMAScript 版本只是忽略它:它是一个什么都不做的表达式语句。

您还可以仅为单个功能打开严格模式:

6.9.2。示例:严格模式

让我们看一个示例,其中草率模式做坏事,严格模式不会:更改未知变量(未通过let或类似创建)创建一个全局变量。

严格模式更好:

assert.throws()要求它的第一个参数,一个函数,在调用时抛出ReferenceError

6.语法 - 图3 测验:高级

参见测验应用程序