2 回答
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
实用程序。
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()();
它奏效了!
长话短说:博士;松散模式下的块处理很奇怪。在块内定义函数时使用严格模式。
添加回答
举报