try {
const val = 'correct value';
(() => {
((arg = val) => {
const val = 'ignored value';
alert(arg);
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
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');
}
ネストされた関数はありません(スニペット3):
try {
const val = 'correct value';
((arg = val) => {
const val = 'ignored value';
alert(val || 'wrong value');
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
変数を上書きしない(スニペット4):
try {
const val = 'correct value';
(() => {
((arg = val) => {
alert(arg);
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
関数の代わりにブロックスコープ(スニペット5):
try {
const val = 'correct value';
{
((arg = val) => {
const val = 'ignored value';
alert(arg);
})();
}
} catch (err) {
alert(err.message || 'Unknown error');
}
スニペット3に基づいて、val
in arg = val
は内部関数のスコープではなく、親スコープから取得する必要があることは明らかです。
最初のスニペットでは、ブラウザーval
は現在のスコープを見つけることができませんが、祖先スコープをチェックする代わりに、一時的なデッドゾーンを引き起こす子スコープを使用します。
これはiOSのバグですか、それともJSの正しい動作を誤解していますか?
このバグはWebpack + Babel + Terserの出力で発生しているため、コードを書き換えてこのバグを回避することはできません。