Javascript:语句和表达式之间的区别?

时间:2012-10-03 06:46:49

标签: javascript expression terminology semantics

我之前问了this问题,在仔细考虑了这个话题之后,我开始想知道“陈述”和“表达”这两个术语的含义之间看似模糊的界限在哪里。所有陈述都是表达式吗? REPL控制台中的返回值来自哪里?它们似乎并不总是具有直观意义。当然,如果您输入1+1,您将获得2,但有时候它的逻辑并不明显。

鉴于在REPL中输入的任何内容都会生成某些值,这是否意味着它可以在JS源代码中用作表达式和独立语句?

以下代码段中可用于_X_的代码字符串也可用于_Y_,反之亦然? if(_X_) _Y_

10 个答案:

答案 0 :(得分:35)

  

所有陈述都是表达式吗?

“无论JavaScript何时需要声明,您也可以编写表达式。这样的语句称为表达式语句。反过来说不成立:你不能写一个JavaScript期望表达式的语句。例如,if语句不能成为函数的参数。“

这是来自Axel Rauschmayer最近关于这个主题的帖子: Expressions versus statements in JavaScript

希望它有所帮助。

答案 1 :(得分:30)

根据MDN

  

表达式是解析为值的任何有效代码单元。

因此,任何可以用作右值的东西都是表达式。

标准是否存在副作用。表达肯定会有副作用。例如。 a=2是一个表达式,因为它具有值(2)并且还为变量赋值。这就是为什么你可以做的事情:

let a;
let b = 1 + (a = 2); // a is now 2 and b is 3

根据上下文,相同(文本)代码块可以被视为表达式语句。例如。文本片段function f(){}是第1行的表达式,以及下面代码中第2行的语句:

let g = function f() {};
function f() {};

因此,某事物是表达式还是声明不能(在一般情况下)通过查看脱离上下文的文本代码来确定;相反,它是语法树中节点的属性,只有在(精神上或实际上)解析代码后才能确定。

此外,也许更重要的是,函数f中的函数语句(a.k.a函数声明)构成了在调用函数f时创建的执行上下文的一部分。但是,函数表达式构成该*执行上下文的一部分。

一个经常被引用的效果是函数声明被“提升”而函数表达式却没有。

如果函数语句占用执行上下文中的空间而函数表达式不占用,则在深度递归中也可以通过实验观察到更微妙的效果。例如。下面的代码使用函数f的无限递归。第一种情况下的函数f包含一个函数表达式,在第二种情况下它包含等效的函数声明:

// Function Expression
{
    let i = 0;
    try {

        function f () {
            i++;
            (function g() {})(); // this is an expression
            f();
        }

        f();

    } catch (err) {
        console.log(`Function Expressions case: depth of ${i} reached. Error: ${err.name}`);
    }
}
// Function Declaration
{
    let i = 0;
    try {
        function f () {
            i++;
            function g() {}; // this is a statement
            g();
            f();
        }

        f();

    } catch (err) {
        console.log(`Functions Declarations case: depth of ${i} reached. Error: ${err.name}`);
    }
}

在我的机器上,我一直得到以下内容(在node.js中):

Function Expressions case: depth of 17687 reached. Error: RangeError
Functions Declarations case: depth of 15476 reached. Error: RangeError

...这与函数声明增加了保存执行上下文所需的空间量,从而更快地占用堆栈空间并因此略微降低​​最大递归深度这一事实是一致的。

答案 2 :(得分:21)

Expression生成或评估某个值。

表达式示例: new Date()生成新的Date对象,没有任何副作用。 [1,2,3]生成一个没有任何副作用的新数组。 5+6产生一个新值11.它只产生新值而没有任何副作用。

语句产生一些行为或做某事,它也有一些副作用。 根据副作用,可以对报表进行分类。

x=5;是一个声明,这里的副作用是x中的赋值或更改。

setTimeout() - 计时器的开始是副作用。

语句通常以分号分隔。

表达式语句是具有一些副作用的表达式,或者只是“具有副作用的表达式”。

表达式声明的例子:

x+=6;是复杂表达式(主表达式组)正在进行的副作用赋值,所谓的表达式语句。

delete a[2];

答案 3 :(得分:12)

最简单的说法是,表达式被评估为产生一个值。另一方面,执行语句使事情发生

答案 4 :(得分:10)

表达式:解析为某个值的代码单元,例如文字&的运营商即可。表达式的例子:

> 3
> 1 + 2
> "expression"
> fn()
> []
> {}


语句:代表一条或多条指令的代码单元,通常以语言保留关键字开头,以显式隐式结束,并带有语句终止。陈述的例子:

> 3;
> let x = 3;
> if () {}
> for () {}
> while () {}

答案 5 :(得分:9)

JavaScript中的所有程序都是由语句组成的,它们以分号结尾,除了用于对零个或多个语句进行分组的块语句。 语句只是执行某些操作但不生成任何值或输出,而表达式会返回一些值。当解释器看到表达式时,它会检索其值并用新值替换表达式。语句用于操纵这些表达式。您可以在此处检查它是表达式还是声明:JavaScript Parser

答案 6 :(得分:3)

我强烈推荐阅读Axel Rauschmayer博士的综合博客文章 的 Expressions versus statements in JavaScript
正如@ ZER0在上面接受的答案中提到的那样。

但我最喜欢的记忆捷径是:

  

表达式:
  可以e E Expression来设置Expressed   ..或E通过打印它   声明:
  ..还要别的吗。

以下是修改的 Anders Kaseorg's Quora answer

语句是执行某些操作的完整代码行。

E非常E xpression可用作声明
(其效果是评估表达式,忽略结果值)

e xpression是e对值E进行评估的代码的任何部分。

  

使用运算符可以将表达式“水平”组合成更大的表达式    S横向平顶

大多数陈述不能用作表达。

  

语句只能通过一个接一个地写,或者用块结构“垂直”组合    2 + 2 3 * 7 1 + 2 + 3 * (8 ** 9) - sqrt(4.0) min(2, 22) max(3, 94) round(81.5) "foo" "bar" "foo" + "bar" None True False 2 3 4.0 垂直运行。

From Quora Post by Ryan Lam:

  

以下是一般的经验法则:如果您可以打印它,或将其分配给变量,那么它就是一个表达式。如果你不能,那就是一个声明。

以下是表达式的一些示例:

if CONDITION:
elif CONDITION:
else:
for VARIABLE in SEQUENCE:
while CONDITION:
try:
except EXCEPTION as e:
class MYCLASS:
def MYFUNCTION():
return SOMETHING
raise SOMETHING
with SOMETHING:

以上所有内容都可以打印或分配给变量。

以下是一些陈述的例子:

x = if CONDITION:
y = while CONDITION:
z = return 42
foo = for i in range(10):

以上结构都不能分配给变量。它们是有目的的语法元素,但它们本身并没有任何内在的“价值”。换句话说,这些结构不会“评估”任何东西。例如,尝试执行以下任何操作都是荒谬的,并且根本不起作用:

cout << m << endl;

答案 7 :(得分:2)

我们有以下两种表达方式:

<强> 1。布尔表达式用于执行语句的块。 enter image description here

<强> 2。算术表达式用于变量赋值,它也充当语句

例如:number = number + 1;

答案 8 :(得分:1)

转到浏览器控制台(Ctrl + Shift + ICommand + Shift + I):

输入对您不明确的代码。

如果浏览器在每一行执行后返回undefined,则返回一条语句。

如果浏览器在每一行执行后返回undefined以外的任何值,则为表达式。

Chrome browser console image showing differences between expression and statement

浏览器控制台的行为就像是对输入的每一行代码使用console.log(statement)。有关更多信息,请参见this

此过程仅用于验证。

但有必要了解:

  1. 表达式return的值,语句没有。

  2. 所有表达式都是语句,但不是。您不能使用语句代替表达式。

答案 9 :(得分:0)

产生值的代码片段称为表达式。逐个写入的每个值(例如22或“心理分析”)都是一个表达式。括号之间的表达式也是一个表达式,适用于两个表达式的二进制运算符或适用于一个表达式的一元运算符。

表达式对应于人类语言中的句子片段,JavaScript语句对应于完整句子。程序是语句列表。

最简单的语句是在其后带有分号的表达式。这是一个程序:

1; !假; 但是,它是一个无用的程序。表达式可以满足于只产生一个值,然后可以由封闭代码使用。声明是独立存在的,因此仅在影响世界时才构成某种意义。

声明可能有副作用。

https://eloquentjavascript.net/02_program_structure.html