【问题标题】:Javascript: difference between a statement and an expression?Javascript:语句和表达式之间的区别?
【发布时间】:2012-09-24 01:39:59
【问题描述】:

我之前问过this这个问题,又想了想这个话题,我开始怀疑“陈述”和“表达”这两个术语的含义之间看似模糊的界限在哪里。所有语句都是表达式吗? REPL 控制台中的返回值来自哪里?它们似乎并不总是具有任何直观意义。当然,如果你输入1+1,你会得到2,但其他时候它的逻辑并不那么明显。

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

下面sn-p中可以用于_X_的代码字符串也可以用于_Y_吗?反之亦然? if(_X_) _Y_

【问题讨论】:

标签: javascript expression terminology semantics


【解决方案1】:

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

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

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

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

浏览器控制台的行为就好像它对输入的每一行代码都使用console.log(statement)。更多信息请参考this

此程序仅用于验证。

但有必要了解:

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

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

【讨论】:

    【解决方案2】:

    产生值的代码片段称为表达式。每个字面书写的值(例如 22 或“精神分析”)都是一个表达式。括号之间的表达式也是一个表达式,就像应用于两个表达式的二元运算符或应用于一个表达式的一元运算符一样。

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

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

    1; !错误的; 不过,这是一个无用的程序。表达式可以满足于只产生一个值,然后可以由封闭代码使用。一个声明是独立存在的,因此只有当它影响到世界时,它才算是某种东西。

    语句可能有副作用。

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

    【讨论】:

      【解决方案3】:

      根据MDN

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

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

      标准是是否存在副作用。表达式肯定会产生副作用。例如。 a=2 是一个表达式,因为它有一个值 (2) 并且还为一个变量赋值。这就是为什么您可以执行以下操作:

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

      根据上下文,同一(文本)代码块可能同时被视为表达式语句。例如。文本 sn-p function f(){} 是下面代码中第 1 行的表达式和第 2 行的语句:

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

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

      此外,也许更重要的是,函数 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}`);
          }
      }
      

      在我的机器上,我始终得到以下信息(在 node.js 中):

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

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

      【讨论】:

      • 很好的答案!谢谢
      • 深度差异来自不同数量的变量。语句样式在范围内引入了一个新变量 g,而表达式样式则没有。在表达式前添加let g= 时,深度将相等
      • @Lauri 执行上下文是保存局部变量的内容。函数表达式不会向执行上下文添加任何内容,而函数声明则可以。另见:stackoverflow.com/a/9384894/274677
      • 这应该是公认的答案。它实际上回答了 OP 问题的所有部分,而且做得非常好。
      • 声明和声明是一样的吗?
      【解决方案4】:

      用最简单的术语来说,表达式被评估以产生一个值。另一方面,执行语句是为了让某事发生

      【讨论】:

      • 一个语句也可以被求值以产生一个值,例如var x = makeSomethingHappen();,所以这个答案不正确。 (你读过接受的答案吗?它已经被覆盖了。)
      • 如果有错误请纠正我,但这不被视为“表达陈述”吗?我了解,也可以对语句进行评估以产生一个值,如您在上面演示的那样。但是表达式和​​语句之间的区别可以像我上面那样总结吗?
      • 当然,但是这个答案仍然没有添加任何未包含在已接受答案中的内容。
      • 除非接受的答案充其量是误导性的。至少这个答案不会误导。
      • @Mogsdad 你错了。如果您更仔细地阅读马库斯所说的“因此,无论是表达式还是语句,都不能(在一般情况下)通过脱离上下文查看文本代码来发音;相反,它是一个节点的属性语法树,只有在(心理或实际)解析代码后才能发音。”然后你可以意识到 var x = makeSomethingHappen();不会产生任何值,因为 var x = whaterver 不会返回任何东西,只有 makeSomethingHappen() 会,但同样,从上面读取状态...
      【解决方案5】:

      我强烈推荐阅读 Axel Rauschmayer 博士的综合博文
      Expressions versus statements in JavaScript
      正如上面@ZER0 接受的答案所述。

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

      表达式:
      e 可以设置为 Equal 为 Expression
      ..orExpressed 打印出来。
      声明:
      ..还要别的吗。


      以下内容修改自
      Anders Kaseorg's Quora answer

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

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

      Expression 是e评估为值e 的代码的任何部分。

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

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

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


      From Quora Post by Ryan Lam:

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

      以下是一些表达式示例:

      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
      

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

      以下是一些语句示例:

      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):
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • 好链接Eldiyar。
        【解决方案7】:

        表达式:解析为值的代码单元,例如literals & operators。表达式示例:

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


        语句:表示一条或多条指令的代码单元,通常以语言保留关键字开始,显式隐式结束em>,带有语句终止符。语句示例:

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

        【讨论】:

          【解决方案8】:

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

          1.布尔表达式用于执行语句块。

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

          例如:number = number + 1;

          【讨论】:

            【解决方案9】:

            表达式产生或评估一些值。

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

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

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

            setTimeout() - 定时器的启动是副作用。

            语句一般用分号隔开。

            表达式语句是具有某些副作用的表达式或简称为“具有副作用的表达式”。

            表达式语句示例:

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

            delete a[2];
            

            【讨论】:

            • x=5; 是一个“表达式语句”。 x=5(不带分号)是一个表达式。是否产生行为或是否完成某事不是定义标准 - 请参阅我的答案以获取更多信息。
            • setTimeout() 一个表达式。它甚至会产生价值。 delete a[5] 也是一个表达式。 “表达式产生或评估某些值。” — 您会考虑 new Array(-1)JSON.parse("x")(function(){"use strict"; x = 2;})()() => {await 3;} 表达式吗?他们都抛出错误。
            【解决方案10】:

            所有语句都是表达式吗?

            “只要 JavaScript 需要一个语句,你也可以写一个表达式。这样的语句称为表达式语句。反过来不成立:你不能在 JavaScript 需要表达式的地方编写语句。例如,if 语句不能成为函数的参数。”

            这是来自 Axel Rauschmayer 最近关于此主题的一篇文章: Expressions versus statements in JavaScript

            希望对你有帮助。

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-05-10
            • 2016-11-18
            • 2012-02-22
            • 2023-04-07
            • 1970-01-01
            相关资源
            最近更新 更多