[英]Why I do not get ReferenceError when calling a function outside a bloxk scope?
I have the following code snippet. 我有以下代码片段。 I do not understand why the last
sayHello
function runs, when instead I would aspect a ReferenceError
as sayHello
it is declared within a bracket scope. 我不明白为什么最后一个
sayHello
函数会运行,而当我将一个ReferenceError
声明为sayHello
它将在方括号范围内声明。
{ sayHello(); // works! function sayHello() { console.log('Hellow world!'); } } sayHello(); // why it is not // ReferenceError
You are hitting an unfortunate backward-compatibility edge-case of the JavaScript language. 您遇到了JavaScript语言的不幸的向后兼容情况。
The ES2015 (ES6) spec of the language was the first to add support for functions inside blocks { ... }
like you have. 该语言的ES2015(ES6)规范是第一个像您一样在块
{ ... }
添加对功能的支持的规范。 Unfortunately most implementations of the language supported them anyway, because it was technically allowed as an extension to the language. 不幸的是,该语言的大多数实现仍然支持它们,因为从技术上讲,它是该语言的扩展。
To allow for old code relying on this extended behavior, the newer versions of the language include Annex B , and in this case specifically B.3.3 Block-Level Function Declarations Web Legacy Compatibility Semantics , which defined the behavior you are seeing. 为了允许旧代码依赖此扩展行为,该语言的新版本包括Annex B ,在本例中特别包括B.3.3块级功能声明Web Legacy兼容性语义 ,它定义了您所看到的行为。
Note the header in the annex: 请注意附件中的标题:
The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser.
当ECMAScript主机是Web浏览器时,需要本附件中定义的ECMAScript语言语法和语义。 The content of this annex is normative but optional if the ECMAScript host is not a web browser.
本附件的内容是规范性的,但如果ECMAScript主机不是Web浏览器,则此内容是可选的。
meaning that implementing this behavior is optional and definitely not something you should rely on. 意味着实现此行为是可选的 ,绝对不是您应该依靠的东西。
The easiest way to never have to sorry about Annex B
optional features is to run your code in strict mode at all times. 不必为
Annex B
可选功能感到后悔的最简单方法是始终在严格模式下运行代码。 Generally I'd say this is always the right call regardless. 通常,我会说这始终是正确的选择。
If you're not familiar, "use strict";
如果您不熟悉,请
"use strict";
is what is called a "directive" and you can include it at the top of your JS file, or at the top of an individual function. 是所谓的“指令”,您可以将其包含在JS文件的顶部,也可以包含在单个函数的顶部。 In this case doing
在这种情况下
"use strict";
{
sayHello();
function sayHello() {
console.log('Hellow world!');
}
}
sayHello();
will throw the errors you expected to see. 会抛出您期望看到的错误。
Moving forward, JavaScript import
/ export
module syntax is also automatically strict, so in the long run the vast majority of code will be strict anyway and not run into this issue. 展望未来,JavaScript
import
/ export
模块的语法也将自动严格,因此从长远来看,绝大多数代码无论如何都将严格,并且不会遇到此问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.