JavaScript:声明与表达式与语句



在过去的几个小时中,我一直试图找到3个区别,而不仅仅是区别,我还一直在尝试找出哪种是同义词,MDN调用全部声明"语句",所以我认为这是事实。但是,我读过的任何文章都没有给我一个备忘单,以区分3(或2,表达式与语句)。

我在语句中注意到的是,它们都以某种方式涉及一个特殊的JavaScript关键字,例如breakforvar。这些文章说,表达式评估某物,而语句执行动作。那是什么函数?它是语句表达混合动力(因为它在调用时都执行动作并返回值)吗?目前,我假设事实并非如此,因为函数调用不涉及JavaScript关键字。

然后有声明,每个声明也是一个声明吗?

我也知道诸如20 + 5 * 2 / 3;之类的表达语句,但是这些实际上没有用吗?为什么有人会用这样的行污染他们的代码?

如果有人可以提出上述问题(或至少其中一些问题),或者有人可以为我提供某种备忘单,我会感到非常高兴。为什么在如此受欢迎的语言中似乎很简单的主题材料很少?

这些术语都有标准定义,所有语言都有,包括JS,关注。我对它们的看法如下:

  • 表达式会产生一个值,并且可以在预期值的任何地方写入值。

  • 另一方面的说法是独立执行单位。它不会返回任何东西。

  • 声明是一个陈述,其中值分配给变量。

  • 所有声明都是语句,但并非所有语句都是声明。

  • 大多数语句和所有声明都包含表达式。

Javadoc还提供了漂亮,简洁的定义:

表达式是由变量,运算符和方法调用组成的构造,它是根据语言语法构造的,它评估为单个值。

语句大致等于自然语言的句子。声明形成了执行的完整单位。

现在,您关于关键字所涉及的理论不正确。这是一个包括关键字的语句:

break;

这不是:

foo();

在第一个示例中,我执行了break,而在第二个示例中,我称为函数。两者都是陈述,但是只有一个包括任何特殊关键字。

函数不是语句。函数呼叫是上述语句。对于返回某些内容的函数,调用也可以是声明:

var bar = foo();

,对于您的最后一个问题,这是因为这仅仅是语义问题的原因。人们不关注这些术语的确切定义。

为了进一步澄清,我建议您查看Axel Rauschmayer的这篇博客文章,该文章专门讨论了JS中的语句和表达式之间的区别。

在过去的几个小时中,我一直试图找到3个区别,而不仅仅是区别,我还试图找出哪种是同义词,mdn调用所有声明"语句",所以我假设是的。

声明是在程序执行之前在编译/加载时间中"声明"变量名称"声明"的任何构造。因此,所有在其各自的范围中声明的名称都已提前已知。

陈述和表达式彼此不同,因为前者没有产生值的值,而后者则没有。因此,可以在预期值的任何地方使用表达式,并且在这些地方不得使用语句。

表达式语句是该语句是单个表达式的一种,或者在需要零或更多子表达的表达式中包含一些。虽然表达式产生结果,但该语句不会。

这是一个表达式:

x = foo() + 2

可以通过在末端添加半隆来明确显示一个完整的表达式语句。

x = foo() + 2;

第一个示例可以包裹在一组Parens中,因为Parens作为分组操作员期望表达式,通常以逗号操作员加入的几种表达式提供。

第二个示例不能包裹在Parens(如果包括分号)中,因为它是一个陈述,并且不会产生一个值,分组运营商期望将其作为其自身的价值接收和返回。

我在语句中注意到的是,它们都以某种方式涉及一个特殊的JavaScript关键字,例如Break或for或var。

大多数语句确实涉及关键字,而不是全部。最值得注意的是,块语句没有关键字。相反,它使用一组卷曲支架来界定其开始和结束。

文章说,表达式评估某物,而语句执行动作。那是什么函数?它是语句表达混合动力(因为它在调用时都执行动作并返回值)吗?目前,我假设事实并非如此,因为函数调用不涉及JavaScript关键字。

JS中有三种功能。如果您要谈论的是使用函数关键字的内容,则可以根据其上下文是声明或表达式。

如果在预期表达式的位置使用该函数,则将其评估为返回新功能对象的表达式。如果不是这样,则预计将是一份声明,它基本上会创建一个带有分配给其函数对象的变量。作为声明,函数名称是必需的(对于变量名称)。作为表达式,它是可选的。

我也知道诸如20 + 5 * 2 / 3;之类的表达语句,但实际上不是无用的吗?为什么有人会用这样的行污染他们的代码?

如果忽略了结果值,则鉴于该示例,这将是没有用的。但这是另一个表达式语句。

foobar();

现在,我们从功能调用中产生了副作用,最有可能且有用。

让我们先谈谈表达式。正如您所说,表达式是评估价值的东西。函数是一个值。另一方面,函数呼叫是一个表达式。

我不同意陈述的表征是"执行动作"的东西。如您所说,调用功能涉及运行该功能体,该功能由语句和声明组成,因此它在"内部"执行操作。

更好地看待它的方法是表达,语句和声明是句法类别。它们是由于试图描述JavaScript语法的结构而产生的。参见例如Ecmascript 8关于表达式,语句和声明的规范。

20 + 5 * 2 / 3;这样的表达式语句确实没有用,因为它没有效果,而陈述的唯一点是其效果。但是还有其他更有用的表达语句:

  • 函数调用:foo();
  • 分配:x = 42;=是操作员,可以在表达式中使用)
  • 增量/减少:i++;(同样,++是操作员)

表达语句以外的其他语句倾向于从一个特殊的关键字开始,以避免句法歧义:解析器希望能够从一开始就可以说出它正在处理哪种构造。因此我们得到:

  • 如果语句:if (EXPR) STMT
  • 在语句中:while (EXPR) STMT
  • 返回语句:return;return EXPR;
  • 等。

但是,有些语句不会以关键字开头:

  • 空语言:;
  • 一个块:{ ... }

最后,声明。在JavaScript中,语句和声明之间的区别在某种程度上是任意的。语法区分两者,但实际上,您通常可以对其进行相同的对待(例如,块语句的内容定义为语句列表list项目的序列,并且语句列表项目定义为要么是声明或声明)。声明包括:

  • 函数声明:function foo() { ... }(包括生成器(function* foo() { ... })和异步功能(async function foo() { ... })等变体)
  • letconst
  • class声明

(但由于某种原因,var foo;被归类为语句,而不是声明。)

最新更新