Конструкция with позволяет использовать для области видимости произвольный объект.
В современном JavaScript от этой конструкции отказались, в строгом режиме она не работает, но ее еще можно найти в старом коде.
Синтаксис:
Любое обращение к переменной внутри with сначала ищет ее среди свойств obj, а только потом — вне with.
Пример
В примере ниже переменная будет взята не из глобальной области, а из obj:
Попробуем получить переменную, которой в obj нет:
Здесь интерпретатор сначала проверяет наличие obj.b, не находит и идет вне with.
Особенно забавно выглядит применение вложенных with:
Свойства из разных объектов используются как обычные переменные… Магия! Порядок поиска переменных в выделенном коде: size => obj => window

Изменения переменной
При использовании with, как и во вложенных функциях — переменная изменяется в той области, где была найдена.
Например:
Почему отказались от with?
Есть несколько причин.
- В современном стандарте
JavaScript отказались от with, потому что конструкция withподвержена ошибкам и непрозрачна.
Проблемы возникают в том случае, когда в with(obj) присваивается переменная, которая по замыслу должна быть в свойствах obj, но ее там нет.
Например:
В строке (2) присваивается свойство, отсутствующее в obj. Об этом говорит сайт https://intellect.icu . В результате интерпретатор, не найдя его, создает новую глобальную переменную window.size.
Такие ошибки редки, но очень сложны в отладке, особенно если size изменилась не в window, а где-нибудь во внешнем LexicalEnvironment.
- Еще одна причина — алгоритмы сжатия JavaScript не любят
with. Перед выкладкой на сервер JavaScript сжимают. Для этого есть много инструментов, например Closure Compiler и UglifyJS. Если вкратце — они либо сжимают код с with с ошибками, либо оставляют его частично несжатым.
- Ну и, наконец, производительность — усложнение поиска переменной из-за
with влечет дополнительные накладные расходы. Современные движки применяют много внутренних оптимизаций, ряд которых не могут быть применены к коду, в котором есть with.
Вот, к примеру, запустите этот код в современном браузере. Производительность функции fastсущественно отличается slow с пустым(!) with. И дело тут именно в with, т.к. наличие этой конструкции препятствует оптимизации.
Замена with
Вместо with рекомендуется использовать временную переменную, например:
Это не так элегантно, но убирает лишний уровень вложенности и абсолютно точно понятно, что будет происходить и куда присвоятся свойства.
Итого
- Конструкция
with(obj) { ... } использует obj как дополнительную область видимости. Все переменные, к которым идет обращение внутри блока, сначала ищутся в obj.
- Конструкция
with устарела и не рекомендуется по ряду причин. Избегайте ее.
Важность: 5
Вторая (2), т.к. при обращении к любой переменной внутри with — она ищется прежде всего в объекте.
Соответственно, будет выведено 2:
[Открыть задачу в новом окне]
Важность: 5
Выведет 3.
Конструкция with не создает области видимости, ее создают только функции. Поэтому объявление var b внутри конструкции работает также, как если бы оно было вне ее.
Код в задаче эквивалентен такому:
Комментарии
Оставить комментарий
Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)