Leo*_*ang 9 javascript scope ios ecmascript-6
try {
const val = 'correct value';
(() => {
((arg = val) => {
const val = 'ignored value';
alert(arg);
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
在 OS X Chrome、OS X Safari、Android Chrome、Windows Chrome、Windows Firefox甚至Windows Edge 上,它会提醒“正确值”。在 iOS Safari 和 iOS Chrome 上,它会警告“找不到变量:val”。
以下代码段均适用于 iOS:
不使用默认参数(代码段 2):
try {
const val = 'correct value';
(() => {
alert(val);
(() => {
const val = 'wrong value';
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
无嵌套函数(代码段 3):
try {
const val = 'correct value';
((arg = val) => {
const val = 'ignored value';
alert(val || 'wrong value');
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
不覆盖变量(代码段 4):
try {
const val = 'correct value';
(() => {
((arg = val) => {
alert(arg);
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
块作用域而不是函数(代码段 5):
try {
const val = 'correct value';
{
((arg = val) => {
const val = 'ignored value';
alert(arg);
})();
}
} catch (err) {
alert(err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
基于代码段 3,很明显val
inarg = val
应该来自父作用域,而不是内部函数的作用域。
在第一个片段中,浏览器val
在当前作用域中找不到,而是使用子作用域而不是检查祖先作用域,这导致了时间死区。
这是 iOS 错误还是我误解了正确的 JS 行为?
这个 bug 发生在我们的 Webpack+Babel+Terser 输出中,所以我们不能只是重写代码来避免这个 bug。
我认为这是参数默认值及其 TDZ的错误实现带来的不良后果。我怀疑 iOS Safari 认为您正在尝试分配给尚未初始化的内容。
仅供参考——错误位置:
解决方法 1 不要初始化与默认参数和外部作用域同名的内部作用域常量
try {
const val = 'correct value';
(() => {
((arg = val) => {
const val_ = 'ignored value'; // <----
alert(arg);
})();
})();
} catch (err) {
console.error(err);
console.error('msg', err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
解决方法2
强制:const
let
try {
let val = 'correct value'; // <----
(() => {
((arg = val) => {
const val = 'ignored value';
alert(arg);
})();
})();
} catch (err) {
console.error(err);
console.error('msg', err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
解决方法 3根本
不要const val
在最里面的闭包中重新初始化:
try {
const val = 'correct value';
(() => {
((arg = val) => {
// const val = 'ignored value'; // <--
alert(arg);
})();
})();
} catch (err) {
console.error(err);
console.error('msg', err.message || 'Unknown error');
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
158 次 |
最近记录: |