在过去的几个小时里,我一直试图找到3之间的差异,而不仅仅是差异,我也一直试图找出哪种是同义词,MDN调用所有声明"语句&#34 ;所以我认为这是真的。但是,我读过的所有文章和SO问题都没有为我提供各种各样的备忘单来区分3(或2,表达式与陈述)。
我在语句中注意到的一点是,它们都以某种方式涉及特殊的JavaScript关键字,例如break
或for
或var
。文章说,表达式评估某些内容,而语句执行操作。什么是功能呢?它是一个语句表达式混合(因为它在调用时都执行一个动作,并返回一个值)?现在,我假设情况并非如此,因为函数调用不涉及JavaScript关键字。
然后有声明,是每个声明也是一个声明?
我也知道像20 + 5 * 2 / 3;
这样的表达语句,但这些几乎没用吗?为什么有人会用这样的行污染他们的代码?
如果有人可以提出上述问题(或者至少其中一些问题),或者有人可以提供某种类型的备忘单,我会非常高兴。为什么在如此流行的语言中,关于某个主题的材料如此简单呢?
答案 0 :(得分:6)
这些术语的标准定义包括所有语言,包括JS。我对它们的看法如下:
表达式生成一个值,可以在期望值的任何地方写入。
另一方面,陈述是一个独立的执行单位。它不会返回任何内容。
声明是一个声明,其中为变量赋值。
所有声明都是声明,但并非所有声明都是声明。
大多数陈述和所有声明都包含表达式。
Javadoc也提供了很好的,简洁的定义:
表达式是由变量,运算符和方法调用组成的构造,它们是根据语言的语法构造的,其值为单个值。
陈述大致相当于自然语言中的句子。声明构成了一个完整的执行单元。
现在,关于必然涉及的关键字的理论是不正确的。这是一个包含关键字的语句:
break;
这是一个没有:
foo();
在第一个例子中,我执行break
,而在第二个例子中,我调用一个函数。两者都是语句,但只有一个包含任何特殊关键字。
函数不是声明。函数调用是一个语句,如上所示。对于返回某事的函数,该调用也可以是声明:
var bar = foo();
对于你的最后一个问题,那里的材料很少的原因是因为这仅仅是一个语义问题。人们不会徘徊在这些术语的确切定义上。
为了进一步澄清,我建议您查看Axel Rauschmayer的this博客文章,该文章专门讨论了JS中语句和表达式之间的区别。
答案 1 :(得分:2)
在过去的几个小时里,我一直试图找到3之间的差异,而不仅仅是差异,我也一直试图找出哪种是同义词,MDN调用所有声明"语句&#34 ;所以我认为这是真的。
声明是"声明"的任何结构。在程序执行之前的编译/加载时存在的变量名。因此,各自范围内的所有声明的名称都是事先已知的。
陈述和表达方式彼此不同,前者不会产生价值,而后者则产生价值。因此,可以在期望值的任何地方使用表达式,并且可以不在那些地方使用语句。
表达式语句是语句是单个表达式的表达式,或者是包含在需要零个或多个子表达式的表达式中的表达式语句。虽然表达式产生了结果,但声明却没有。
这是一个表达式:
x = foo() + 2
可以通过在末尾添加分号来明确显示完整表达式语句。
x = foo() + 2;
第一个示例可以包含在一组parens中,因为作为分组运算符的parens需要一个表达式,通常由逗号运算符连接的几个表达式提供。
第二个示例不能包含在parens中(如果包含分号),因为它是一个语句,并且不会产生一个值,分组操作符期望接收该值并将其作为自己的值返回。
我在语句中注意到的一点是它们都以某种方式涉及一个特殊的JavaScript关键字,如break或for或var。
虽然大多数语句确实涉及关键字,但并非所有语句都涉及。最值得注意的是,block语句没有关键字。相反,它使用一组花括号来分隔它的开始和结束。
文章说,表达式会评估某些内容,而语句会执行操作。什么是功能呢?它是一个语句表达式混合(因为它在调用时都执行一个动作,并返回一个值)?现在,我假设情况并非如此,因为函数调用不涉及JavaScript关键字。
JS中有三种功能。如果您正在谈论使用function关键字的那些,那么根据其上下文,它可以是声明或表达式。
如果在期望表达式的地方使用该函数,则将其计算为返回新函数对象的表达式。如果没有,那么它应该是一个声明,它基本上创建一个赋值给它的函数对象的变量。作为声明,函数名称 required (对于变量名称)。作为表达,它是可选的。
我也知道像
20 + 5 * 2 / 3;
这样的表达语句,但这些几乎没用吗?为什么有人会用这样的行污染他们的代码?
如果结果值被忽略,那么在给定示例的情况下它将是无用的。但这是另一个表达陈述。
foobar();
现在我们有一个函数调用的副作用,这很可能是期望和有用的。
答案 2 :(得分:2)
我们首先谈谈表达式。正如你所说,表达式是一个计算值的东西。函数是一个值。另一方面,函数调用是一个表达式。
我不同意将声明描述为“执行行动”的内容。正如你所说,调用一个函数涉及运行函数体,它由语句和声明组成,因此它在“内部”执行动作。
更好的方法是查看表达式,语句和声明是语法类别。它们源于试图描述JavaScript语法的结构。参见例如expressions上的ECMAScript 8规范,statements, and declarations。
像20 + 5 * 2 / 3;
这样的表达式语句确实没用,因为它没有任何效果,而声明的唯一要点就是它的效果。但是还有其他更有用的表达式语句:
foo();
x = 42;
(=
是一个运算符,可以在表达式中使用)i++;
(类似地,++
是运营商)表达式语句以外的语句倾向于以特殊关键字开头,以避免语法歧义:解析器希望能够从一开始就告诉它正在处理什么类型的构造。因此我们得到:
if (EXPR) STMT
while (EXPR) STMT
return;
或return EXPR;
但是,有些语句不是以关键字开头的:
;
{ ... }
最后,声明。在JavaScript中,语句和声明之间的区别有些武断。语法区分两者,但在实践中,您通常可以将它们视为相同(例如,块语句的内容被定义为语句列表项的序列,并且语句列表项被定义为是声明或声明)。声明包括:
function foo() { ... }
(包括诸如生成器(function* foo() { ... }
)和异步函数(async function foo() { ... }
)之类的变体)let
和const
class
声明(但出于某种原因,var foo;
被归类为陈述,而不是声明。)