简体   繁体   English

为什么在bloxk范围之外调用函数时没有收到ReferenceError?

[英]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.

相关问题 直接从成员函数访问成员变量时,为什么会出现ReferenceError? - Why do I get a ReferenceError when accessing member variables from a member function directly? 如何从回调函数获取值到外部作用域? - How do I get a value from a callback function to the outside scope? 调用函数时出现ReferenceError - ReferenceError when calling function 在setTimeout中使用音频时,为什么会出现ReferenceError? - Why do I get a ReferenceError when using audio in setTimeout? 为什么会收到“未捕获的ReferenceError:未定义$(匿名函数)” - Why do I get an “Uncaught ReferenceError: $ is not defined (anonymous function)” 为什么我会得到这个JavaScript ReferenceError - Why do I get this JavaScript ReferenceError 为什么我会收到“ReferenceError:未定义测试” - Why do I get “ReferenceError: test is not defined” 反应为什么我在调用作为参数传递的 function 时收到错误“Uncaught TypeError: createTask is not a function”? - REACT Why do I get the error "Uncaught TypeError: createTask is not a function" when calling a function passed as a parameter? 为什么在调用不带参数的函数时出现未定义的错误? - Why do I get an undefined error when calling a function without parameter? 为什么在调用有效函数时出现类型错误? | 角度2 - Why do I get a Type Error when calling a valid function? | Angular 2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM