Определение объема объявлений функций внутри операторов with - PullRequest
0 голосов
/ 24 февраля 2020

Предисловие : использование with является не рекомендуется в JavaScript по уважительной причине. Это может привести к путанице в коде и проблемам с совместимостью (например, при добавлении новых свойств во встроенные объекты). Этот вопрос не о том, следует ли использовать with, а об определенном spe c поведении with.

Должен ли работать следующий код?

let foo = {};
with(foo) {
  function bar() {
    console.log("hello");
  }
}
bar();

Работает в Chrome 80, но не в Firefox 72: TypeError: bar is not a function.

Редактировать : Оказывается, эта ошибка возникает только при вставке в консоль Firefox (https://i.imgur.com/WTG3iiX.png), не при запуске кода в документе HTML.

Но обратите внимание, что это TypeError, а не ReferenceError (то есть bar is not defined) , Чтобы подтвердить это, мы можем добавить console.log("bar" in window) перед bar(); и заметить, что выводит true в Firefox, тогда как если вы пишете это перед кодом, он выводит false. Таким образом, в Firefox приведенный выше код имеет эффект установки window.bar в undefined.

. Это прекрасно работает как в Firefox, так и в Chrome:

if(true) {
  function bar() {
    console.log("hello");
  }
}
bar();

Просто как я и ожидал, так как объявление function foo() {...} является областью действия функции. Так что, если нет ничего странного в with областях видимости блоков, похоже, что это Firefox ошибка?

1 Ответ

1 голос
/ 24 февраля 2020

Мне не удалось воспроизвести проблему с Firefox 73, поэтому поведение Firefox могло измениться.

Тем не менее, см. MDN по теме блоков :

В строгом режиме, начиная с ES2015, функции внутри блоков ограничиваются этим блоком. До ES2015 функции на уровне блоков были запрещены в строгом режиме.

IIR C, взаимодействие между правилами подъема и блоками было неопределенным, что приводило к разному поведению в различных JS двигателях. Это не столько ошибка Firefox, сколько ошибка в определении самого языка.

Избегайте объявлений функций в блоках.

...