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 中復制了該行為。我安裝了1 并在本地運行它(將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();
1 使用非常方便的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()();
它奏效了!
長話短說:博士;松散模式下的塊處理很奇怪。在塊內定義函數時使用嚴格模式。
添加回答
舉報