【问题标题】:Why Chrome still keep silent when using functions inside blocks in "strict mode"? [duplicate]为什么 Chrome 在“严格模式”下使用块内的函数时仍然保持沉默? [复制]
【发布时间】:2016-08-13 20:27:39
【问题描述】:

当我使用如下代码时,我对 JS "strict mode"; 还是很陌生:

function outer(){

"use strict";
    var ctype;

    function inner(){

        if(ctype!=undefined){
            function hello1(){
                console.log("hello1");
            }
            hello1()
        }else {
            function hello2(){
                console.log("hello2");
            }
            hello2();
        }

    }

    return inner;

}

var inner = outer();

inner();

我想知道为什么 Chrome(版本 49)没有给出错误,但 Node.js 会给出“SyntaxError:在严格模式代码中,函数只能在顶层或立即在另一个函数中声明。 "

This table指出我的Chrome应该报错。

【问题讨论】:

  • @DanD。谢谢,所以这意味着 Chrome 不使用我的代码而是更改代码然后在严格模式下检查它?
  • 添加 [node.js] 标签,因为这个问题是将其行为与 Chrome 进行比较(而不是与规范或其他内容进行比较)。
  • 似乎是一个错误。解析器应该在它有机会运行之前抛出一个 SyntaxError。甚至不需要调用,就像在这个更简单的演示中一样:jsfiddle.net/6zr12q7v
  • ES6 没有添加允许它的功能,是吗?由于块现在可以创建范围,我想知道现在是否允许这种语法。
  • @squint Huh... 根据this post,你是对的,ES6 修改了function 声明以使用块作用域而不是函数作用域。我以为他们只对 let/const/class 这样的新结构使用块作用域。看来我们有答案了。

标签: javascript node.js google-chrome ecmascript-6


【解决方案1】:

您使用的 Node.js 版本 (0.12.9) 使用旧版本的 V8 JavaScript 引擎 (3.28.71.19),它不遵循 ECMAScript 6 中添加的新函数声明范围规则。您正在使用的 Chrome (49) 使用新版本的 V8 (4.9.385),它确实支持新规则,至少在严格模式下是这样。

在 ECMAScript 6 之前,函数声明的作用域是包含函数。例如:

ECMAScript 5

function main() {
  if (true) {
    function example() {};

    console.log(example); // function example() {}
  }

  console.log(example); // function example() {}
}

这被认为是令人困惑的行为,因此在严格模式下被禁止,导致您在 Node 中看到错误。

在 ECMAScript 6 中,函数声明的范围改为最近的块。块是包含在两个括号 ({ ... }) 之间的任何一系列语句,例如在 if 语句之后。

ECMAScript 6

function main() {
  'use strict';

  if (true) {
    function example() {};

    console.log(example); // function example() {}
  }

  console.log(example); // ReferenceError: example is not defined
}

这种行为是故意的,不太容易混淆,因此在严格模式下是允许的。

但是,测试这有点令人困惑,因为 Chrome 目前仅在严格模式下启用一些 ES6 规则。

【讨论】:

  • 这个粗略的答案是基于对一些资源的快速浏览;我以前没有使用过这种行为,并且可能误解了它。任何澄清(或下面发布的更好的答案)将不胜感激。 (提示,提示,downvoter。;)
  • 谢谢,但是很抱歉,我没有完全理解你的意思。我没有在我的代码中使用任何 ES6 功能。我想我的情况是即使我只使用 ES5 语法,但是一旦我指定 "strict mode",它在 Chrome 和 Node 中的行为是不同的
  • @Kuan 我明白了,这很奇怪。以前,Chrome 遵循 ES5 的规则。它现在开始遵循 ES6 中的一些规则,首先是严格模式。您没有在代码中使用任何全新的 ES6 特性这一事实并不重要; Chrome 仍将应用新的 ES6 规则,其中包括 function 定义的新行为。这种新行为允许它们以严格模式(而不是函数的顶层)在块内部,而旧行为则不允许。 (我想尝试改进我的答案,使其更清楚一点,但我必须去赴约。)
  • 这是一个非常好的和明智的功能。通过利用块作用域的新现实来平息规范与实现之间的冲突。
  • “在 ECMAScript 6 之前,函数声明的作用域是包含函数。” 明确一点:在 ES5 中,块内的函数声明实际上是一个语法错误,但是大多数引擎决定以一种或另一种方式接受它。例如,Chrome 和 Firefox 实现了非常不同的行为。另见ecma-international.org/ecma-262/6.0/…
猜你喜欢
  • 2012-05-27
  • 2015-02-11
  • 2012-11-09
  • 2018-08-17
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2014-07-24
相关资源
最近更新 更多