TGViewer
Дивовижний світ веброзробки Дивовижний світ веброзробки @babichdev · 2.91K subscribers
Post #153 2.23K
Багатогранний плюс.
Що ж, як і обіцяв, рубрика "Бабіч спозоривсь на ютубі" продовжується, і сьогодні ми поглянемо до простого на перший погляд оператора +. Чому на перший погляд? Бо якщо копнути глибше, виявиться, що там не все так однозначно.

Коли ми використовуємо + з числовими типами, він поводиться рівно так, як ми й очікуємо ще зі школи — додає два значення, продукує суму. Є, щоправда, маленький нюанс з BigInt, той занадто гордий, аби товаришувати з іншими типами і займається арифметикою лише з іншими BigInt.

Однак цікаві досліди починаються, коли ми спробуємо змішати у виразі числові і нечислові значення, або ж пододавати між собою не числа. Відразу на думку спаде "додавання" рядочків. Тільки, насправді, це не додавання, а операція конкатенації — злиття послідовних рядків в один.

І тоді оператор +, не змінюючи вигляду, змінює роль — він перетворюється з оператора арифметичного додавання на оператор конкатенації.

І ось ми підійшли до моменту, в якому я заплутався на етері. Річ у тому, що коли у виразі хоча б один операнд є рядком, другий операнд буде примусово приведено до рядка. У мене ж в голові звідкись сплило, що порядок операндів може вплинути на поведінку оператора. Насправді це не відповідає дійсності, і на поведінку операторів вплинуть лише типи операндів.

Хоча є один трюк, який може призвести до такого хибного висновку. Увівши в консолі наступні вирази, ми отримаємо такі результати:
{} + 1 // 1
1 + {} // 1[object Object]

Виглядає цілком переконливо. Але є нюанс. {} на першому рядочку не сприймається інтерпретатором як літерал обʼєкта. Знаходячись на початку рядка, {} сприймається як пустий блок коду. І в цьому випадку вираз перетворюється на + 1, що й дає в результаті одиницю.

Якщо ж ви цей же вираз присвоїте змінній, усе встане на свої місця:
let x  = {} + 1 // [object Object]1


Поки ви геть не заплутались, хто кому куди плюсує, втуліть вподобайку цьому допису, не зволікайте

А що це за вираз такий + 1, і чому він валідний? Все просто — в такому записі оператор + робить ще одне перевтілення, і стає унарним плюсом. В такій іпостасі оператор намагається перетворити операнд на число. З перемінним успіхом, звичайно, якщо ваш рядок не є репрезентацією числа. І тут би пасувало глибше розібратися, що таке ця "репрезентація числа", але мені б хотілося, аби для вас це зробили більш глибоко обізнані в цій темі люди.

Я ж просто познайомлю вас з цим дивовижним явищем. Отже, перше поверхневе припущення може звучати так: "Рядок може бути приведеним до числа, якщо він містить лише цифри, ʼ+ʼ, ʼ-ʼ і десятковий роздільник, та не містить літер". Логічно.
+"1000" // 1000
+"43.5" // 43.5


Але, насправді, ми можемо привести до числа рядки, що містять літери! Не усі, правда — лише визначені, і лише якщо вони знаходяться на певних позиціях. Бо тоді ми дивимось не просто на рядок, а на запис числа в певній нотації:
+"0x10" // Шістандцяткове 16
+"0b1010"; // Двійкове 10
+"0o16" // Вісімкове 14
+"10e2" // Науковий запис 1_000
// але
+"1n" // NaN, хоча 1n це BigInt


Глибше в ці нотації я також занурюватись не буду, залишу це задоволення вам для самостійного опанування.

Ви помітили, що при початку пояснення унарного плюса я в прикладі написав пробіл після плюса, а потім вже ні? Так от, обидва записи рівноцінні: "+ 1" і "+1".

І саме цю особливість використовують в іншому прикладі "сМіШнОгО jS", створюючи банан з допомогою барана:
("b" + "a" + + "a" + "a").toLowerCase()
> "banana"


Причина криється саме в поведінці оператора +, а саме в цьому фрагменті: + + "a". Хоч він і записується з пробілом, але обробляється ось так: + +"a", де вже унарний плюс спробує привести рядок "a" до числа, в чому зазнає невдачі і поверне той самий NaN.

Вираз тепер набуде виду "b" + "a" + "NaN" + "a" і спокійнісінько конкатенується в baNaNa, який потім майстерно приховають з .toLowerCase.

Ну і хто тепер баpнан, ненависники JavaScript, га?

Товариство, а ви як, дивуєтесь плюсу, чи знаєте усі його нюанси назубок? ;)

@babichdev
  • ❤ 99
  • 🔥 22
  • 👏 9
  • 🤔 2
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 →