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

wwa*_*waw 54 javascript expression terminology semantics

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

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

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

ZER*_*ER0 38

所有陈述都是表达式吗?

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

这是来自Axel Rauschmayer最近关于此主题的文章: 表达式与JavaScript中的陈述

希望能帮助到你.

  • 对于有兴趣了解更多有关javascript语句和表达的人的一些进一步阅读,即.差异,关键字等:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators以及https://developer.mozilla.org/en-US/docs/Web/JavaScript的/参考/语句 (3认同)

Mar*_*tus 34

MDN称:

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

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

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

let a;
let b = 1 + (a = 2); // a is now 2 and b is 3
Run Code Online (Sandbox Code Playgroud)

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

let g = function f() {};
function f() {};
Run Code Online (Sandbox Code Playgroud)

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

此外,也许更重要的是,函数内部的函数语句(也称为函数声明)f构成了在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}`);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Function Expressions case: depth of 17687 reached. Error: RangeError
Functions Declarations case: depth of 15476 reached. Error: RangeError
Run Code Online (Sandbox Code Playgroud)

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

  • 函数表达式有自己的执行上下文,通常寿命较短,因此对堆栈空间利用率有积极影响.

  • 这应该是公认的答案。它实际上回答了OP问题的所有部分,而且做得非常漂亮。 (3认同)

Pra*_*een 21

表达式生成或评估某些值.

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

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

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

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

语句通常用分号分隔.

表达式语句是具有一些副作用或简单地"具有副作用的表达"的表达.

表达式语句的示例:

x+=6; 复杂表达式(主表达式组)正在进行赋值,这是一种副作用,因此称为表达式语句.

delete a[2];
Run Code Online (Sandbox Code Playgroud)

  • `x = 5;`是一个"表达式语句".`x = 5`(没有分号)是一个表达式.行为是否产生或者某些事情是否已经完成*不是*定义标准 - 请参阅我的答案. (7认同)

U-w*_*ays 16

在最简单的术语中,表达式被评估以产生值.另一方面,执行语句使某些事情发生.

  • 除了接受的答案充其量是误导性的.至少这个答案不会误导. (3认同)
  • 如果我错了,请纠正我,但这不是“表达式语句”吗?我知道也可以评估语句以产生如上所述的值。但是表达式和​​语句之间的区别可以像我上面所做的那样进行总结吗? (2认同)

小智 10

表达式:解析为值的代码单元,例如,文字运算符.表达式的示例:

> 3
> 1 + 2
> "expression"
> fn()
> []
> {}
Run Code Online (Sandbox Code Playgroud)


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

> 3;
> let x = 3;
> if () {}
> for () {}
> while () {}
Run Code Online (Sandbox Code Playgroud)


Eld*_*bek 9

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


She*_*man 5

我强烈建议阅读 Axel Rauschmayer 博士的综合博客文章
表达式与 JavaScript
中的语句,如上面@ZER0 接受的答案中所述。

但我最喜欢的记忆快捷方式是:

表达式:
e可以设置EExpression
.. 或Expressed通过打印它。
声明:
..其他。


以下内容是从
Anders Kaseorg 的 Quora 回答中修改而来

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

Every Expression 可以用作语句
(其作用是对表达式求,并忽略结果值)

但是Expression 是代码的任何部分,它e评估为 value e

表达式可以使用运算符“横向”组合成更大的表达式。
E有一个水平平坦的顶部

大多数语句不能用作表达式。

语句只能通过一个接一个地编写或使用块结构来“垂直”组合。
S相比之下,垂直运行。


来自 Ryan Lam 的 Quora Post:

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

以下是一些表达式示例:

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
Run Code Online (Sandbox Code Playgroud)

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

以下是一些声明示例:

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:
Run Code Online (Sandbox Code Playgroud)

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

x = if CONDITION:
y = while CONDITION:
z = return 42
foo = for i in range(10):
Run Code Online (Sandbox Code Playgroud)


KJ *_*han 5

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

输入对您来说不明确的代码。

如果浏览器undefined在每一行执行后都返回,则它是一个语句。

如果浏览器undefined在每行执行之后返回任何值,则它是一个表达式。

Chrome 浏览器控制台图像显示表达式和语句之间的差异

浏览器控制台就好像它console.log(statement)用于输入的每一行代码一样。有关更多信息,请参阅内容。

此程序仅用于验证。

但有必要了解:

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

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