try {
const val = 'correct value';
(() => {
((arg = val) => {
const val = 'ignored value';
alert(arg);
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
On OS X Chrome, OS X Safari, Android Chrome, Windows Chrome, Windows Firefox, and even Windows Edge, it alerts "correct value". On iOS Safari and iOS Chrome, it alerts "Can't find variable: val".
The following snippets all work on iOS:
Not using default argument (snippet 2):
try {
const val = 'correct value';
(() => {
alert(val);
(() => {
const val = 'wrong value';
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
No nested functions (snippet 3):
try {
const val = 'correct value';
((arg = val) => {
const val = 'ignored value';
alert(val || 'wrong value');
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
Not overriding variable (snippet 4):
try {
const val = 'correct value';
(() => {
((arg = val) => {
alert(arg);
})();
})();
} catch (err) {
alert(err.message || 'Unknown error');
}
Block scope instead of function (snippet 5):
try {
const val = 'correct value';
{
((arg = val) => {
const val = 'ignored value';
alert(arg);
})();
}
} catch (err) {
alert(err.message || 'Unknown error');
}
Based on the snippet 3, it's clear that the val in arg = val should come from the parent scope, not the scope of the inner function.
In the first snippet, the browser can't find val in the current scope, but instead of checking the ancestor scopes, it uses the child scope, which causes the temporal dead zone.
Is this an iOS bug or am I misunderstanding the proper JS behavior?
This bug is occurring in our Webpack+Babel+Terser output, so we can't just rewrite the code to avoid this bug.
