Аргументи Javascript за замовчуванням з визначенням блоку не вдається лише в iOS


9

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вхід arg = valповинен надходити з батьківської області, а не сфери внутрішньої функції.

У першому фрагменті браузер не може знайти valв поточному масштабі, але замість того, щоб перевіряти область дії предка, він використовує дочірнє поле, що спричиняє тимчасову мертву зону.

Це помилка в iOS чи я неправильно розумію правильну поведінку JS?

Ця помилка трапляється у нашому Webpack + Babel + Terser, тому ми не можемо просто переписати код, щоб уникнути цієї помилки.

Відповіді:


3

Я думаю, що це небажаний наслідок невдалої реалізації значень за замовчуванням Param та їх TDZ . Я підозрюю, що iOS Safari вважає, що ви намагаєтесь призначити те, що ви ще не ініціалізували.

Для довідки - місце помилки:

введіть тут опис зображення


Обхід 1 Не ініціалізуйте внутрішню область const w / те саме ім'я, що параметр за замовчуванням та зовнішній діапазон

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');
}

Обхід 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');
}

Обхід 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');
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.