Javascript 为什么函数被描述为块作用域

Javascript 为什么函数被描述为块作用域,javascript,ecmascript-6,Javascript,Ecmascript 6,我正在阅读以下内容: 函数声明 是块范围的,比如let 在全局对象中创建属性 (在全局范围内),如var 吊装位置:与何处无关 函数声明在其作用域中被提及,它总是被创建的 在范围的开头 好吧,函数一直都是函数作用域。我原以为ES6中可能发生了一些变化,但没有: function a() { if (true) { // defined inside the block and is hoisted to the top of that block z(

我正在阅读以下内容:

函数声明

  • 是块范围的,比如let
  • 在全局对象中创建属性 (在全局范围内),如var
  • 吊装位置:与何处无关 函数声明在其作用域中被提及,它总是被创建的 在范围的开头
好吧,函数一直都是函数作用域。我原以为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中它发生了变化吗

好吧,函数一直都是函数作用域。我想ES6可能发生了一些变化

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

因此,规范必须跳转,特别是在浏览器的松散模式下

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

“严格使用”;
功能测试(){
如果(真){
函数foo(){
log(“foo调用”);
}
}
试一试{
foo();//引用错误
}捕获(e){
log(“错误:+String(e));
}
}

test()我认为这本书以(现有)函数声明为例来解释
let
是如何融入到图中的。这是因为您是在松散模式下执行它的。在严格模式下,它应该和预期的一样。@TJCrowder在firefox上我得到了这个语法错误:在严格模式代码中,函数只能在顶层声明,也可以直接在另一层中声明function@Eineki:那一定是Firefox的一个相当旧的版本(“old”在ES2015 support land:-)中是一个相当相对的术语)。我在Firefox v50.1.0中得到了预期的
ReferenceError