为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript 代码块有时会抛出错误

JavaScript 代码块有时会抛出错误

杨魅力 2022-12-29 16:42:49
我正在使用代码块来模拟 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。
查看完整描述

2 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

问题是代码处于松散模式并且您在块中声明一个函数。块中的函数声明仅在 ES2015 中标准化,嗯,它们在严格模式下有意义,但在松散模式下它们……很奇怪。


在strict mode中,您的代码可以正常工作,可能如您所料,也可能不会。bob可以访问b...并且在该块之外既bob不能b访问也不能访问,除非你做一些事情将它们暴露在它之外。


这是一个示例,您可以使用它在 Safari 和 iOS Safari 上进行测试(我只有后者可用)。这个版本报错:


<script>

window.onerror = e => {

    document.body.insertAdjacentText("beforeend", String(e));

};

</script>

<script>

{

    let bob = 5;

    function b() {

        document.body.insertAdjacentText("beforeend", bob++);

    }


    b();

}

</script>

错误是:


ReferenceError: Can't find variable: bob


这个版本有效:


<script>

window.onerror = e => {

    document.body.insertAdjacentText("beforeend", String(e));

};

</script>

<script>

"use strict"; // <============================

{

    let bob = 5;

    function b() {

        document.body.insertAdjacentText("beforeend", bob++);

    }


    b();

}

</script>

我还在最新版本的 JavaScriptCore(Apple 的 JavaScript 引擎)v265499 中复制了该行为。我安装了¹ 并在本地运行它(将console.log/更改insertAdjacentText为print,这在大多数原始引擎可执行文件中都可用)并在松散模式下出现相同的错误,而不是在严格模式下。


如果你想b在街区外可用,你最好做这样的事情:


"use strict";

const b = (() => {

    let bob = 5;

    return function b() {

        console.log(bob++);

    };

})();

b();

这要大得多,但是......或者,使用let:


"use strict";

let b;

{

    let bob = 5;

    b = function b() {

        print(bob++);

    };

}

b();

¹ 使用非常方便的jsvu实用程序



查看完整回答
反对 回复 2022-12-29
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

根据错误消息,Safari 将您的块解释为对象文字。语法是有效的,但 Safari 似乎对此感到窒息。


当我在自己的控制台中尝试这个时,我能够通过紧跟在块后面的语句来让它工作:


{ let bob = 5; function b(){ console.log(bob++); } } console.log('foo');

但是,这似乎在不创建闭包的情况下将函数提升到块作用域之外,导致ReferenceError声称它找不到 variable bob。


我尝试将它显式包装在一个函数中并使用use strict声明启动该函数,以防它未在严格模式下运行,因为这会改变行为:


function strict() {

  'use strict';

  {

    let bob = 5;

    function b() {

      console.log(bob++);

    }

    return b;

  } 

}

strict()();

它奏效了!


长话短说:博士;松散模式下的块处理很奇怪。在块内定义函数时使用严格模式。


查看完整回答
反对 回复 2022-12-29
  • 2 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信