with
не рекомендоване, оскільки може бути джерелом заплутаних помилок та проблем із сумісністю. Дивіться абзац "Мінуси для однозначності" у розділі "Опис", щоб дізнатись більше.Оператор with розширює ланцюжок областей видимості для інструкції.
Синтаксис
with (expression) statement
expression
- Додає наданий вираз до ланцюжка областей видимості, який використовується під час обчислення інструкції. Круглі дужки навколо виразу є обов'язковими.
statement
- Будь-яка інструкція. Щоб виконати більше однієї інструкції, скористайтесь блоком ({ ... }), щоб згрупувати ці інструкції.
Опис
JavaScript шукає некваліфіковане ім'я у ланцюжку областей видимості, пов'язаних з контекстом виконання скрипта чи функції, що містить це некваліфіковане ім'я. Оператор 'with' додає наданий об'єкт у початок цього ланцюжка під час обчислення своїх інструкцій. Якщо некваліфіковане ім'я, що використовується у інструкціях, співпадає з властивістю з ланцюжка областей видимості, це ім'я зв'язується з властивістю та об'єктом, що містить цю властивість. Інакше, викидається помилка ReferenceError
.
with
не рекомендоване та заборонене у строгому режимі ECMAScript 5. Рекомендованою альтернативою є присвоєння об'єкта, чиї властивості вам потрібні, тимчасовій змінній.Плюси та мінуси для швидкодії
Плюси: Оператор with
може допомогти зменшити розмір файлу, скорочуючи необхідність повторювати довгі посилання на об'єкти без погіршення швидкодії. Зміна ланцюжка областей видимості, спричинена використанням 'with', не є затратною для обчислення. Використання 'with' звільнить інтерпретатор від розбору повторюваних посилань на об'єкти. Зауважте, однак, що у багатьох випадках ця перевага досягається використанням тимчасової змінної для зберігання посилання на необхідний об'єкт.
Мінуси: Оператор with
спочатку спричиняє пошук усіх імен на вказаному об'єкті. Таким чином, усі ідентифікатори, що не є членами вказаного об'єкта, шукатимуться у блоці 'with' набагато повільніше. У випадках, коли швидкодія важлива, 'with' слід використовувати лише у тих блоках коду, які звертаються до членів вказаного об'єкта.
Мінуси для однозначності
Мінус: З оператором with
стає важко зрозуміти, людині чи компілятору JavaScript, чи буде некваліфіковане ім'я знайдене у ланцюжку областей видимості, і, якщо так, то в якому об'єкті. Отже, у наступному прикладі:
function f(x, o) {
with (o) {
console.log(x);
}
}
Лише коли функція f
викликана, змінна x
або буде знайдена, або ні, а, якщо буде знайдена, то або в o
, або (якщо такої властивості не існує) у об'єкті активації f
, де x
іменує перший формальний аргумент. Якщо ви забудете визначити x
у об'єкті, який передаєте другим аргументом, або в разі якоїсь схожої помилки чи плутанини, ви не отримаєте помилку -- лише неочікувані результати.
Мінус: Код, що використовує with
, може бути несумісним знизу вгору, особливо при використанні з чимось інакшим, ніж простий об'єкт. Розглянемо цей приклад:
function f(foo, values) {
with (foo) {
console.log(values);
}
}
Якщо ви викличете f([1,2,3], obj)
у середовищі ECMAScript 5, то посилання values
всередині блоку with
поверне obj
. Однак, ECMAScript 2015 вводить властивість values
у Array.prototype
(таким чином, доступну у кожному масиві). Отже, у середовищі JavaScript, яке підтримує ECMAScript 2015, посилання values
всередині блоку with
може повернути [1,2,3].values
. Однак, конкретно у цьому прикладі Array.prototype
було визначено з values
у об'єкті Symbol.unscopables
. Якби не це, ми б побачили, як важко було б його відлагоджувати.
Приклади
Використання with
Наступний оператор with
вказує, що об'єкт Math
є об'єктом за замовчуванням. Інструкції, що йдуть після with
, посилаються на властивість PI
, а також методи cos
та sin
без зазначення об'єкта. JavaScript припускає, що об'єктом цих посилань є Math
.
var a, x, y;
var r = 10;
with (Math) {
a = PI * r * r;
x = r * cos(PI);
y = r * sin(PI / 2);
}
Специфікації
Сумісність з веб-переглядачами
BCD tables only load in the browser