为啥函数被描述为块范围
Posted
技术标签:
【中文标题】为啥函数被描述为块范围【英文标题】: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
如何融入图片。
那是因为你在松散模式下执行它。在严格模式下,它应该符合预期。
【参考方案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
。以上是关于为啥函数被描述为块范围的主要内容,如果未能解决你的问题,请参考以下文章
为啥条件块中的函数声明在 Chrome 而不是 Firefox 中提升到函数范围?
当函数返回时,指向超出范围的对象的 C++ 指针 - 为啥会这样?