【问题标题】:Why functions are described as block scoped为什么函数被描述为块范围
【发布时间】:2017-06-07 19:50:02
【问题描述】:

我正在阅读this book on ES6 并且有以下内容:

函数声明…

  • 是块范围的,例如 let。
  • 在全局对象中创建属性 (在全局范围内),如 var.
  • 被吊起:独立于何处 函数声明在其范围内被提及,它总是被创建 在范围的开头。

AFAIK,函数一直是函数作用域的。我认为 ES6 中可能发生了一些变化,但没有:

function a() {
    if (true) {
        // defined inside the block and is hoisted to the top of that block
        z();
        function z() { console.log ('z')}
    }

    z();
}

// but is also hoisted to the function scope
a(); // works OK

实际上,它们似乎是块作用域:

function a() {
    if (false) {
        // defined inside the block and is hoisted to the top of that block
        z();
        function z() { console.log ('z')}
    }

    z(); // error
}

那么它在 ES6 中是否发生了变化?

【问题讨论】:

  • 我认为这本书以(现有的)函数声明为例来解释let如何融入图片。
  • 那是因为你在松散模式下执行它。在严格模式下,它应该符合预期。

标签: javascript ecmascript-6


【解决方案1】:

AFAIK,函数一直是函数作用域的。我认为 ES6 中可能发生了一些变化

确实如此:在 ES2015 之前,规范根本没有涵盖在块中声明的函数。支持它们是允许的扩展,但不是规范的一部分。

因此,规范不得不跳槽,尤其是在浏览器的松散模式下。

strict 模式下,您会在兼容的引擎上发现函数声明确实是块范围的:

"use strict";

function test() {
  if (true) {
    function foo() {
      console.log("foo called");
    }
  }
  try {
    foo(); // ReferenceError
  } catch (e) {
    console.log("Error: " + String(e));
  }
}
test();

在兼容的 JavaScript 引擎上(例如任何最新版本的 Chrome 中的 V8,或任何最新版本的 Firefox 中的 SpiderMonkey),您将在上面获得ReferenceError

【讨论】:

  • @TJCrowder 在 firefox 上我得到这个 SyntaxError:在严格模式代码中,函数只能在顶层或立即在另一个函数中声明
  • @Eineki:那一定是一个相当老的 Firefox 版本(“老”在 ES2015-support-land 中是一个相当相对的术语 :-))。我在 Firefox v50.1.0 中得到了预期的 ReferenceError
猜你喜欢
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多