TGViewer
Дивовижний світ веброзробки Дивовижний світ веброзробки @babichdev · 2.91K subscribers
Post #339 2.16K
#js_in_action
В кожній мові програмування існує безліч способів вистрілити собі в ногу, і JavaScript — не виключення. Буквально днями мені пригадався один з таких способів, який я навіть колись (дуже давно) використовував в продакшн-коді.

Мова йде про оператор with.
const user = { name: "Elvira" };

with (user) {
console.log(name); // Elvira
}


Якщо спробувати пояснити це явище швидко й просто, то нічого не вийде. Але я спробую. В першу чергу нам потрібно пригадати поняття scope chain. Це ланцюжок контекстів, у якому рушій шукає змінну, до якої ми звертаємось у коді.

І зазвичай мова йде про лексичні скоупи, створені або функціями, або іншими блоками коду за допомогою фігурних дужок. А with просто ніби "пристібає" свій обʼєкт у ланцюжок пошуку імен, тому всередині блоку прості звертання можуть неочікувано резолвитись у властивості цього об’єкта.

with втручається саме в звертання до простих імен. Усередині такого блоку JavaScript спочатку намагається трактувати name як властивість переданого об’єкта, і лише потім шукає це ім’я далі по scope chain. Звертання через явний об’єкт, як-от user.name, цієї проблеми не мають.
const user = { name: "Elvira" };
const name = "Oliver";

with (user) {
console.log(name);
}


У цьому прикладі буде виведено "Elvira", а не "Oliver", тому що with змушує JavaScript спочатку шукати name у user.

Вам уже мало стати очевидним, що with має набагато більше недоліків, аніж сумнівних вигод. І це правильне відчуття. Він вносить сумʼяття на усіх рівнях: людині важко зрозуміти, що ж мав на увазі автор — чи локальну змінну, чи властивість, чи змінну глобальну; рушій не може оптимізувати такий код, бо не може безпечно припускати, до чого саме посилається кожне імʼя всередині with; лінтери й інші інструменти також можуть сумніватися в тому, до чого саме звертається просте ім’я всередині блоку.

Яскравим прикладом є потенційне перекриття глобальних та локальних імен:
const user = { name: "Elvira", console: true };

with (user) {
console.log(name);
}


Проблема тут полягає в тому, console буде резолвитись як user.console, а не як глобальний об’єкт console. Насправді, існує механізм обходу глобальних імен через [Symbol.unscopables], але розібратися з ним я залишаю моєму цікавому читачу.

Хоч with і не вилучено зі специфікації ECMAScript повністю, його використання, мʼяко кажучи, не заохочується. В strict mode він заборонений, і лишається лише як частина зворотньої сумісності.

Якщо вважати, що призначенням with було спрощення доступу до властивостей обʼєкту на письмі, то нині у нас є набагато кращі й надійніші способи спрощено звертатися до таких властивостей, наприклад, та сама деструктуризація:
const user = { name: "Elvira"};
const { name } = user;
console.log(name);


Попри добрі наміри, with виявився конструкцією, що втручається в один із фундаментальних механізмів JavaScript — пошук ідентифікаторів через scope chain. І через це привносить неочікувану невизначеність, через що код стає неочевидним і складним для аналізу.

Що почитати:
MDN: with statement
MDN: JavaScript Guide — Working with objects

Що почитати душнілам:
ECMAScript: with statement
ECMAScript: Object Environment Records
ECMAScript: GetIdentifierReference

P.S. Навіщо я взагалі вирішив розповісти про таку стародавню й дивну чудасію? Бо одним з моїх принципів є чергове складне речення: "треба знати не лише як правильно, але і як не правильно, щоб не писати неправильно, не знаючи, що це неправильно".

@babichdev
  • ❤ 26
  • 👍 18
  • 🔥 5
More from @babichdev
  1. Sep 30, 2026Товариство, запрошую вас цієї суботи, 3 жовтня, на Fwdays Tech Summit — онлайн конференцію…
  2. Sep 28, 2026#збір_на_авто_для_21 Товариство, почнімо тиждень з доброго діла. Я би дуже хотів, аби ми ц…
  3. Sep 27, 2026Знайшов своє старезне резюме. Аж пустив скупу сльозу за тими часами, коли навіть з таким м…
  4. Sep 25, 2026Днями на редіті побачив допис, в якому автор питав, чому його лічильник часу на сторінці з…
  5. Sep 23, 2026Який ШІ найкращий для навчання? Відповідь проста — той, з яким ви чогось навчились. ШІ це…
  6. Sep 18, 2026Оце я, канєшна, провтикав. Конфа завтра, 19 вересня. Ще встигаєте взяти квиточок.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →