简介
几年前,我在当地的一个编码训练营教网络开发,一个学生问我这个问题。
在JavaScript中,"语句 "和 "表达式 "之间有什么区别?
我觉得我知道这个问题的答案,但当我试图解释时,我却无法用语言来表达。我有一种感觉,但我的实际知识却出奇地模糊。
没有什么比教书更令人谦卑的了😅。学生们很善于发现我们理解中的 "模糊点"。
我后来认识到,这个问题极其重要。它是一个承重的混凝土支柱,将有助于支持大量的JavaScript知识。
这对React开发者来说尤其如此。你不得不记住的那些JSX规则,以及总是忘记遵守的那些规则,大部分都是这个语句/表达式二元性的结果。
在这篇博文中,我将分享我对这种区别的一些顿悟,以及我们如何在日常工作中使用这些信息。
意向受众
本教程假定你对基本的JavaScript语法很熟悉,但在其他方面的编写是为了方便初学者。
在本教程的最后,我们将探讨一些React的含义,这部分需要一些React的经验。如果你不是React开发者,可以跳过这一部分;希望本教程的其他部分仍然能提供大量的价值。
[
链接到这个标题
](www.joshwcomeau.com/#expression…
表达式的核心是产生一个值的一段JavaScript代码。
例如,这些都是表达式。
-
1
→ 产生1
-
"hello"
→ 产生"hello"
-
5 * 10
→产生50
-
num > 100
→产生 或true
false
-
isHappy ? "🙂" : "🙁"
→产生一个表情符号 -
[1, 2, 3].pop()
→产生数字3
表达式可以包含表达式。例如,在这一大段JS代码中,你能数出多少个表达式?猜一猜,然后拖动滑块,看它们各自高亮。
高亮显示的表达式:-
[
链接到这个标题
](www.joshwcomeau.com/#statements…
一个JavaScript程序是一连串的语句。每个语句都是计算机做某事的指令。
这里有一些JavaScript语句的例子。
js
js
js
我喜欢这样想:语句是支撑我们程序的刚性结构,而表达式则填充了细节。
语句通常有表达式的 "槽"。我们可以把任何我们喜欢的表达式放到这些槽里。
例如,声明一个变量有一个表达式槽。
js
我们可以在这个槽中使用我们先前看到的任何表达式。
js
就有效语法而言,表达式是可以互换的。如果一个语句有一个表达式槽,我们可以把任何表达式放在那里,代码就会运行。我们不会得到一个语法错误。
*话虽如此,*我们还是会遇到其他问题。例如,下面的代码在语法上是有效的,但如果我们试图运行它,就会使浏览器标签崩溃,因为它会导致无限循环。
js
[
链接到这个标题
](www.joshwcomeau.com/#a-handy-tr…
想知道一个大块的JS是表达式还是语句?试着把它注销吧!
js
如果它运行,代码就是一个表达式。如果你得到一个错误,它就是一个语句(或者,可能是无效的JS)。
作为奖励,我们甚至可以看到表达式的解析结果,因为它将被打印在浏览器的控制台中!这一点很重要。
这是因为**所有的函数参数必须是表达式。**表达式产生一个值,这个值将被传递到函数中。语句不会产生一个值,所以它们不能被用作函数参数。
即使作为一个有经验的开发者,我也非常依赖console.log
。它是一个奇妙的多功能工具!
[
链接到这个标题
](www.joshwcomeau.com/#expression…
这里有一个表达式:1 + 2 + 3
。
如果我们创建一个只包括这个表达式的JS文件,会发生什么?让我们想象一下,我们把下面的内容保存为test.js
。
js
这个文件有多少个语句?是零还是一?
情况是这样的:表达式不能单独存在。它们总是语句的一部分。所以在这种情况下,我们有一个看起来像这样的语句。
js
除了它的表达式槽,这个语句基本上是空的。我们的表达式1 + 2 + 3
填充了这个槽,我们的语句就完成了。
换句话说,下面所有的行都是有效的语句。
js
通常,教程会错误地指出,表达式就是语句,但这并不完全正确。表达式和语句是不同的东西。但是语句有可能在不提供任何额外字符的情况下包裹住表达式。想想看,这就像用透明的收缩膜包住一个三明治。
语句通常以分号结尾,它标志着语句的结束。对于某些语句来说,分号是不必要的,比如if
语句、while
循环和函数声明。
[
链接到这个标题
](www.joshwcomeau.com/#practical-…
如果你以前使用过React,你可能知道斜括号({
和}
)允许我们在JSX中嵌入JavaScript的位子,像这样。
jsx
这就是React的神奇之处;我们可以使用JavaScript的全部功能。
但是有一个问题--我们不能把任何JavaScript放在大括号里。具体来说,我们只能包括表达式,而不是语句。大括号本质上是在我们的JSX中创建一个表达式槽。
如果我们试图在这里嵌入一个语句,比如一个if/else语句,我们会得到一个错误。
jsx
这是因为语句不会产生一个值,只有表达式会产生一个值。如果我们想在JSX中嵌入if/else逻辑,我们需要使用一个三元操作符表达式。
jsx
这似乎是一个奇怪的JWX/React限制,但它实际上是一个JavaScript限制。
我想我们经常责怪React的一些看似武断的规则,比如组件必须返回一个顶层元素。但更多时候,React只是在警告我们有一个JavaScript限制。
理解语句和表达式的区别是解开React警告和bug整个类别的重要第一步。我们还需要了解JSX是如何编译成JavaScript的,以及React的调和与渲染周期是如何工作的......不过,可惜这些话题已经超出了本篇博文的范围
顺便说一下,我正在创建一个全面的React课程,我希望在我学习React的时候有这样的资源。它被称为The Joy of React,你今天就可以注册获取更新信息了
[
链接到这个标题
](www.joshwcomeau.com/#in-summary…
一个JavaScript程序由一连串的语句组成。每个语句都是一个做某事的指令,比如创建一个变量,运行一个if/else条件,或者开始一个循环。
表达式产生一个值,这些值被塞进语句中,就像一个超级任天堂的弹夹,可以改变超级任天堂的动作。
表达式始终是语句的一部分,即使该语句是空的。例如,下面的代码运行一个循环*,没有*使用for
语句,但它仍然包括一个 "空包装 "语句。
js
这种区别可能需要一段时间才能变得直观,但希望这篇博文能澄清一些问题
最后更新
2022年7月11日