JavaScript 代码块有时会抛出错误

我正在使用代码块来模拟 la C 中的静态函数变量。这是基本设置:


{

    let bob = 5;

    function b() {

        console.log(bob++);

    }

}

现在在 chrome 中,这个编译很好,没有任何抱怨。然而,在 Safari 中,我得到一个


SyntaxError: Unexpected identifier 'bob'. Expected a ':' following the property name 'let'.


我不知道是什么导致了这种差异,因为 Chrome 和 Safari 都处理 ECMAScript 6。


杨魅力
浏览 91回答 2
2回答

慕勒3428872

问题是代码处于松散模式并且您在块中声明一个函数。块中的函数声明仅在 ES2015 中标准化,嗯,它们在严格模式下有意义,但在松散模式下它们……很奇怪。在strict mode中,您的代码可以正常工作,可能如您所料,也可能不会。bob可以访问b...并且在该块之外既bob不能b访问也不能访问,除非你做一些事情将它们暴露在它之外。这是一个示例,您可以使用它在 Safari 和 iOS Safari 上进行测试(我只有后者可用)。这个版本报错:<script>window.onerror = e => {&nbsp; &nbsp; document.body.insertAdjacentText("beforeend", String(e));};</script><script>{&nbsp; &nbsp; let bob = 5;&nbsp; &nbsp; function b() {&nbsp; &nbsp; &nbsp; &nbsp; document.body.insertAdjacentText("beforeend", bob++);&nbsp; &nbsp; }&nbsp; &nbsp; b();}</script>错误是:ReferenceError: Can't find variable: bob这个版本有效:<script>window.onerror = e => {&nbsp; &nbsp; document.body.insertAdjacentText("beforeend", String(e));};</script><script>"use strict"; // <============================{&nbsp; &nbsp; let bob = 5;&nbsp; &nbsp; function b() {&nbsp; &nbsp; &nbsp; &nbsp; document.body.insertAdjacentText("beforeend", bob++);&nbsp; &nbsp; }&nbsp; &nbsp; b();}</script>我还在最新版本的 JavaScriptCore(Apple 的 JavaScript 引擎)v265499 中复制了该行为。我安装了¹ 并在本地运行它(将console.log/更改insertAdjacentText为print,这在大多数原始引擎可执行文件中都可用)并在松散模式下出现相同的错误,而不是在严格模式下。如果你想b在街区外可用,你最好做这样的事情:"use strict";const b = (() => {&nbsp; &nbsp; let bob = 5;&nbsp; &nbsp; return function b() {&nbsp; &nbsp; &nbsp; &nbsp; console.log(bob++);&nbsp; &nbsp; };})();b();这要大得多,但是......或者,使用let:"use strict";let b;{&nbsp; &nbsp; let bob = 5;&nbsp; &nbsp; b = function b() {&nbsp; &nbsp; &nbsp; &nbsp; print(bob++);&nbsp; &nbsp; };}b();¹ 使用非常方便的jsvu实用程序。

眼眸繁星

根据错误消息,Safari 将您的块解释为对象文字。语法是有效的,但 Safari 似乎对此感到窒息。当我在自己的控制台中尝试这个时,我能够通过紧跟在块后面的语句来让它工作:{ let bob = 5; function b(){ console.log(bob++); } } console.log('foo');但是,这似乎在不创建闭包的情况下将函数提升到块作用域之外,导致ReferenceError声称它找不到 variable bob。我尝试将它显式包装在一个函数中并使用use strict声明启动该函数,以防它未在严格模式下运行,因为这会改变行为:function strict() {&nbsp; 'use strict';&nbsp; {&nbsp; &nbsp; let bob = 5;&nbsp; &nbsp; function b() {&nbsp; &nbsp; &nbsp; console.log(bob++);&nbsp; &nbsp; }&nbsp; &nbsp; return b;&nbsp; }&nbsp;}strict()();它奏效了!长话短说:博士;松散模式下的块处理很奇怪。在块内定义函数时使用严格模式。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript