Дивовижний світ веброзробки – Telegram
Дивовижний світ веброзробки
2.91K subscribers
83 photos
7 videos
1 file
183 links
Дивовижний світ веброзробки — тепер і в твоєму телеграмі. Анонси відео з YouTube-каналу «Сергій Бабіч та Дивовижний світ веброзробки», стріми, авторські статті та цікаві знахідки.

youtube.com/@babichweb

Реклами та інтеграції обговоримо
Download Telegram
Ну, а ввечері перед сном ще запитаю про досвід.
У кожного свій шлях, але цікаво — на якому етапі ви зараз?
Final Results
19%
🐣 Трейні / Курси
20%
🪴 Junior
33%
🔧 Middle
16%
🧭 Senior
8%
🦉 Tech / Team Lead
4%
👀 Я просто подивиться
Дивитись можна, чіпати не можна?
Часто виникає потреба “вимкнути” якийсь елемент, щоб він узагалі жодним чином не реагував на дії користувача: ні на кліки, ні на фокус. Зазвичай це або pointer-events: none, або event.preventDefault(), чи якісь інші трюки. А то й усе вкупі з tabindex="-1".

Однак в HTML уже давно існує спосіб надійно позбавити елемент будь-якої інтерактивности, а ба більше — викинути його з accessibility tree, “заховавши” від очей скринрідерів.

Це атрибут inert, який відображає однойменну властивість DOM-елемента:
<main id="my-content" inert>
<p>Щось неважливе</p>
</main>


Що в JS робиться ось так:
document.getElementById('my-content').inert = true;


Якщо зробити елемент інертним, то весь його вміст стане повністю й остаточно неактивним для користувача, а також повністю зникне з радарів скринрідерів. І так, “розінертити” дочірні елементи не вийде — атрибут inert не має значення false, і інертність завжди наслідується.

І ви не будьте інертними — ставте вподобайки та поширюйте допис.


inert входить до Baseline з 2023 року й підтримується всіма основними браузерами. Проте, у Safari (очікувано) є один нюанс: текст усередині inert-елемента все ще можна знайти при пошуку по сторінці (Cmd+F).

Чи можна його використовувати вже? Абсолютно так. За винятком цього невеликого бага, inert працює однаково й передбачувано в усіх браузерах, дозволяючи одним-єдиним атрибутом уникнути потреби городити купу костилів лише для того, щоб користувач не міг клікнути або табнутись у якийсь елемент.

Цим фактом особливо спішу з вами поділитись, бо сам дізнався про inert, обираючи тему для наступного допису.

А для вас це теж новина?

MDN

@babichdev
🔥11620
На DOU Day за 500₴
Дарую квиток за донат на ЗСУ!

Друзі, цьогоріч я вперше виступаю на DOU Day 2025 — і дуже хочу, щоб хтось із вас був там теж. Це чудова нагода відвідати крутезний захід, і зустрітися особисто. Усе, що треба — просто долучитися до збору на РЕБ для в/ч А3892.

Кожні 500 грн — ще один шанс виграти.
Ціль — 260 000 грн.

🔗 Банка:
https://send.monobank.ua/jar/4Pc6zfoth2

💳 Картка:
4441111124945795

Переможця оберу серед усіх донатерів у банці — в п'ятницю, 9 травня.


в коментарях є фото листа-прохання від військової частини

@babichdev
🔥21
Нещодавно я розповідав про такий метод HTML-елемента, як closest, який шукає найближчий батьківський елемент, що відповідає заданому селектору. А сьогодні хочу поділитися з вами іншим методом, що нічого не шукає, але відповідає на питання — "А ось цей елемент точно справжній сантехнік той, що треба?"

І це — Element.matches, який просто перевіряє елемент, на якому він викликаний, на предмет відповідності селектору:
<div class="container">
<div class="my-element"></div>
</div>

<noscript>
el.matches('.container .my-element'); // true
</noscript>


Якщо повного співпадіння не буде, то й поверне він false:
el.matches('.container'); // false


На відміну від closest, matches перевіряє суто цільовий елемент і не шукає інших збігів. Звичайно, якщо обом методам дати однаковий і точний селектор — обидва спрацюють позитивно. Але якщо селектор “не точний”, closest цілком може повернути когось із батьків, а от matches скаже чітке “ні”.

Поки ми тут, не забудьте поставити вподобайку та поширити допис ;)


Що цікаво, обидва методи працюють зі складними селекторами, включно з псевдокласами, тобто чудово справляться з отаким:
:not(.container:first-child):hover .my-element


Але у випадку з тим же :not можуть бути нюанси. Коли я бавився з цим прикладом, то селектор вище чудово спрацьовував, а от ось такий:
.container:not(:first-child):hover .my-element

уже чомусь ні, хоча в CSS цей селектор працює без проблем

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

Звичними нам методами це вимагало б купу переборів DOM і перевірок, а так — один кучерявий селектор і справу зроблено!

Підтримується абсолютно всіма актуальними бравзерами і є частиною Baseline.

🔗 MDN

⚡️@babichdev

***
P.S. До речі, ви вже взяли участь в розіграші квитка на DOU Day усього за 500 гривень? Якщо ні — не зволікайте!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥447👏4
Знаєте, коли я востаннє відчув невимовну радість від коду?
Вчора. І це було ніби вперше.

З роками, з досвідом, коли вже зробив, бачив, пробував стільки всього, починає здаватися, що тебе вже нічого не здивує. Ти тримав у руках jQuery 1.4 і верстав під IE6. Ти бачив стрімкий зліт і ганебну смерть AngularJS. Спостерігав на власні очі за народженням React — і досі чекаєш, коли згасне гайп навколо нього.

Але навіть після всього цього… досі по-дитячому щиру радість викликає одне просте:

ВОНО РОБЕ.

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

І от ти записуєш цю думку кодом — і воно робе! Саме так, як уявляв: швидко, точно, надійно. І відчуваєш не просто задоволення. Відчуваєш — це зробив я!

Ці моменти — найцінніше для мене в щоденній роботі.

Так, наша робота давно вже ширша, ніж просто написання коду. І, будьмо чесні, кодинг — далеко не головна частина.

Але саме з цих маленьких митей відкриття й складається моє захоплення фахом.

***
P.S. Лишився лише один день до завершення розіграшу квитка на DOU Day 2025. Ви вже долучились?

P.P.S. А від чого ж я відчув таку невимовну радість учора? Якщо цей допис збере понад сотню реакцій і 500 переглядів — поділюся з вами завтра.

@babichdev
108🔥27
Що ж це за задача, рішення якої принесло мені днями стільки задоволення, що я аж цілий допис написав про це відчуття?

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

Очевидно, що таблиця не підійде (але я б її не взяв і так). Тому вибір очевидний — CSS Grid.

Отут постає кілька вимог, які дещо можуть завадити швидкій та наївній імплементації:
ширина першої колонки — спільна, бо там номер картки;
висота — довільна, однак grid за замовчуванням має однакові рядки;

І тут я згадав про subgrid:
.container {
display: grid;
grid-template-columns: min-content 1fr;
}

.card {
display: grid;
grid-template-columns: subgrid;
}


Тут нюанс — якщо між головною сіткою і "наслідувачем" є обгортки, їм усім треба так само “прокинути” цю сітку:
:where(.wrapper-1, .wrapper-2, …, .wrapper-n, .card) {
display: grid;
grid-template-columns: subgrid;
}


І тоді сітка буде спільна для усіх елементів, незалежно, як вони між собою вкладені. Але лишається ще одне — динамічна висота картки. Тут мені трошки довелося подумати, але рішення виявилося настільки ж елегантним, як і простим:
.card {
height: max-content;
}


Voila! — картки в сітці кожна має свою власну висоту!

І от коли все стало на свої місця, клацнуло як останні детальки LEGO, от тоді я й відчув ту мимолітну ейфорію, про яку писав.

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

🔔 Тим часом розіграш квитка на DOU Day усього за 500 грн відбудеться уже сьогодні ввечері! Тож не зволікайте, аби не впустити таку нагоду!

@babichdev

.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥498👏8
Розіграш завершено!

(оновлено о 18:02)

Друзі, банку розбито, переможця визначено, і квиточок сьогодні вже буде у нього.

Дякую усім, хто долучився, разом ми зібрали і наблизили збір до завершення ще на 25 642 гривні!

Гарного усім вечора!
🔥12
#цього_тижня

Зазирнули по той бік ViewTransition у React і зʼясували, що це всього-на-всього обгортка над браузерним View Transition API.

— Познайомилися з атрибутом inert, який дозволяє зробити елемент видимим для ока, але невидимим для всього іншого.

— Розібрали, чим корисний метод Element.matches() і чим він відрізняється від Element.closest().

— Я поділився, які маленькі речі приносять мені справжнє задоволення в коді.

— А наступного дня показав, який саме код надихнув мене на попередній допис.

А ще — разом з вами ми зібрали 25 642 грн на користь ЗСУ!

Який із дописів цього тижня сподобався вам найбільше? Напишіть у коментарях 👇

👍@babichdev

.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥266👏4
Що приховують три крапки?
Вітаю, друзі! Сьогодні розповім вам про деякі неочевидні підводні камені так званого spread-оператора. Я сподіваюсь, ви вже в курсі, для чого він існує, тож перейду відразу до прихованих нюансів.

Порядок важливий
Коли ви "підмішуєте" обʼєкт, то значення будуть застосуватись в порядку додавання в новий обʼєкт:
{ a: 1, b: 2, ...{ b: 3 } } // { a: 1, b: 3 }

{ ...{ b: 3 }, a: 1, b: 2 } // { a: 1, b: 2 }


Останнє входження ключа перезаписує попереднє. Spread — це не злиття, а послідовне копіювання полів з обʼєктів у новий.

undefined в масивах і обʼєктах
Ви спокійно можете розгорнути той же undefined або null в обʼєкт, а от з масивом такий трюк не пройде.
{ ...undefined } // {}

[...undefined] // 💥 TypeError


Усе через те, що масив вимагає, аби вхідний обʼєкт був Iterable, тобто такий, яким можна пройтися з Symbol.iterator, і nullish значення, очевидно такими не є. А от звичайний обʼєкт не такий вибагливий, і йому достатньо будь-якого значення, до якого можна застосувати Object.keys. У випадку з null та undefined цей метод просто поверне порожній список.

Object ⇄ Array? Ні.
Рівно з тієї самої причини ми можемо розмазати масив в обʼєкт, але не можемо зробити навпаки:
[...{ a: 1 }] // 💥 TypeError: object is not iterable

{ ...[1, 2] } // { 0: 1, 1: 2 }


Spread у масиві очікує ітерабельність — тобто наявність Symbol.iterator. Обʼєкти цього не мають (за замовчуванням), тому розгортання летить з помилкою.

Натомість spread в обʼєкті потребує лише перелічуваних властивостей. А масив — це просто обʼєкт із числовими ключами, які чудово підходять під це визначення.

... не любить порожнечі
const a = [1, , , , 5]; // [1, empty × 3, 5]
const b = [...a]; // [1, undefined, undefined, undefined, 5]

console.log(1 in a); // false
console.log(1 in b); // true


Spread-оператор не просто “копіює” масив — він перетворює його дірки на явно присутні undefined.

У масиві a на індексах 1, 2, 3 немає значень — це так звані дірки (sparse elements). Але при ...a вони ущільнюються: JavaScript вставляє на їхнє місце undefined, і ці індекси стають реально присутніми в структурі масиву.

... не копіює вміст обʼєкта
Технічно. Він поверхнево копіює перший рівень масива або обʼєкта. І якщо там примітивні значення, то можна сказати, це "копія". Але якщо є вкладеності, то ... скопіює посилання на них, а не зробить клоновані копії.
const original = {
value: 1,
nested: { deep: true },
};
const copy = { ...original };

copy.nested.deep = false;
console.log(original.nested.deep); // false


А ще ... копіює виключно перший видимий рівень. Тобто прототип, неперелічувані властивості, символи — усе піде під ніж, і ви отримаєте стерильну копію.

***
Якщо дізналися щось нове — напишіть у коментарях, що саме здивувало чи стало у пригоді.

А далі — обирати вам! Про що буде наступний допис?


🔥 — Дірки в масивах: як вони зʼявляються і що ламають
❤️ — Symbol.iterator: ітерабельність під капотом
🤔 — Чи настільки різні масиви та обʼєкти?

@babichdev
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6043🤔23👏2
Порожнеча дивиться на тебе.

Масиви в JavaScript мають одну цікаву особливість — вони можуть бути "дірявими". Якщо дуже коротко — ми можемо явно присвоїти значення будь-якому індексу, і якщо цей індекс не є наступним після останнього значення, то утвориться розрив.
let arr = ['one', , 'three'];
// ['one', empty, 'three'];

arr[100] = 'value';
// ['one', empty, 'three', empty × 97, 'value']


Дірка — не undefined! Хоча при звертанні до "дірки" вам і поверне undefined, насправді в самому масиві його не буде. Дірка означає повну відсутність значення за індексом, він просто не ініціалізований. Це випливає з того, що масив — це підвид обʼєкту, просто з певним інтерфейсом для впорядкування ключів.

По факту, масив з діркою, наприклад той самий ['one', ,'three'], у обʼєктному записі виглядатиме так:
{ 0: 'one', 2: 'three' }

Індекс 1? Його просто немає.

Дірява поведінка
Дірки поводяться по своєму, і не завжди передбачувано. Візьмемо до прикладу масив [1, , 3] та порахуємо квадрати його значень:
[1, , 3].map(x => x * x) // [1, empty, 9]


А тепер точнісінько такий масив, але замінимо дірку явним undefined:
[1, undefined, 3].map(x => x * x) // [1, NaN, 9]


Помітили різницю? Так от, map, forEach, filter, reduce, every, some просто ігнорують дірки, перестрибують їх. А for...of, for навпаки — зазирнуть у кожну дірочку.

А JSON.stringify взагалі перетворює дірки в масиві на… null.

До речі, як визначити, що це саме дірка, а не просто undefined? Перевірити наявність індекса в масиві. Якщо ключа немає, то це — дірка:
const arr = ['one', , 'three'];
1 in arr; // false


Дірка як палиця в колесі.
Така поведінка, очікувано, може призводити до багатьох дивних ситуацій, особливо при клонуванні чи порівнянні масивів. Ще більше збиватиму з пантелику той факт, що [].length віддає не фактичну кількість ключів, а "найбільший індекс + 1", що теж не додає впевнености при роботі з дірявими масивами.

Також JavaScript рушії не дуже полюбляють діряві масиви, бо робота з ними вимагає відмови від багатьох оптимізацій, які можна застосувати до безпереревних масивів. Я не буду вдаватися в деталі, лише зазначу, що це дійсно впливає і на споживання памʼяті, і на внутрішню швидкодію. Звичайно, ви не помітите різниці на масиві з десятком дірок, але якщо їх 100 000, 1 000 000, то втрати будуть відчутні.

Заштопати всі дірки!
Найочевидніша порада — не допускайте дірок. Якщо вам потрібна подібна структура, краще використати обʼєкт з власним ітератором. Якщо ж в руки потрапив такий масив, то його краще ущільнити: чи то зібрати лише реальні значення в інший масив, чи то заповнити дірки явним undefined — у будь-якому разі рушій вам подякує, а потім подякуєте і ви собі.

💬 А ви стикались із дірками в проді?
Чи, може, самі колись ненароком залишили? Поділіться досвідом у коментарях!
І якщо було цікаво — не забудьте поширити допис або кинути лінк колезі.


🔗 @babichdev
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7118👏3🤔2
Виграти квиток на JavaScript fwdays'25 усього за сто гривень? Та легко!

Товариство, хто ще не придбав квиток на конференцію, але дуже хочe туди потрапити? Маєте шалену нагоду виграти один з двох Full Ticket квиточків та відвідати цю чудову подію і зустрітися з, до прикладу, Іллєю Климовим, чи Юрієм Артюхом. Ну і я десь там пробігатиму.

Усе, що треба — просто долучитися до збору на РЕБ для в/ч А3892.

Кожні 100 грн — ще один шанс виграти.
Фінальна ціль — 260 000 грн.

Посилання на банку
https://send.monobank.ua/jar/ABkKH6rr3u

Номер картки банки
4441111125077309

Переможців оберу наступної середи, 20 травня, рандомом від monobank.

@babichdev

в коментарях є фото листа-прохання
🔥64
Синьйор мусить знати все!
Ні. Не все.

Радше так: синьйор не має знати напамʼять увесь MDN. Як і мідл. Як і джун. Як і техлід. Взагалі, розробник не має знати всього напамʼять — це не показник експертности.

Розробка — це не контрольна робота. Це не про “знаєш або не знаєш”. Це про вміння орієнтуватися, коли стикаєшся з новим. Про вміння формулювати запит, знайти джерело, зрозуміти, перевірити, застосувати. Це — робота з невизначеністю.

Так, є база, без якої нікуди, і яка постійно змінюється. Є зони відповідальности. Є глибина, яку справедливо очікують від розробника певного рівня. Але навіть у синьйора в голові не вміщається весь Intl API, увесь Grid, або всі edge-кейси WebRTC. І це — нормально.

Найкращі розробники, з якими я працював — не ті, хто “все памʼятає”. А ті, хто не втрачає холодної голови, коли чогось не знає. Хто знає, як і де шукати. Хто не боїться питати. І хто не знецінює себе за пробіл — бо знає, що пробіл не означає порожнечу.

Коли я не знаю щось на співбесіді — це не провал. Це точка росту. Коли забуваю щось на етері — це не соромно. Це звичайний обсяг людської памʼяті, а не причина знецінювати себе.

Знання — це не інвентар, який мусить бути повним.
Це навичка працювати з невідомим.
Уміння рухатись уперед, навіть коли карти в голові ще не розкладені.

Між “я не знаю, як дізнатися” і “я не знаю, але розберусь” — ціла прірва. І справжній фахівець — це той, хто цю прірву давно перейшов.

Ти не мусиш усе знати.
Ти мусиш вміти дізнатися.


💬 А ви як ставитеся до моментів, коли чогось не знаєте?
Чи було таке відчуття, що «мусив же це знати!» — і що з ним робили?

P.S. На fwdays за 100 гривень?! Це можливо взагалі? Я кажу — так!

🔗 @babichdev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11237👏6
А сьогодні я на DOU Day ) Тож хто тут ще є — підходьте, будем робить селфіки і обмінюватись контактами ;)
🔥6411
Навіщо ходити на конференції та мітапи?
Хтось скаже — там обовʼязково треба слухати доповіді й набиратись нових знань. Хтось — що доповіді не важливі, а треба виключно нетворкатись. Хтось узагалі мовчки лутає мерч зі стендів партнерів.

А я вам скажу — на конференціях треба займатись усім! Якщо вас не дуже приваблює тема доповіді — сміливо йдіть пити каву та знайомитись. Втомились від розмов — ласкаво просимо до зали, там якраз виступає Бабіч. І не забудьте пробігтись партнерськими “будками” — там, окрім стікерів, шкарпеток та іншого дрібʼязку, іноді розігрують класні подарунки в обмін на ваші повні контакти, включно зі скрином з Дії. Але без жартів: саме на стендах я познайомився з багатьма HR, PR та рекрутерами, з якими досі спілкуємось. Одне таке знайомство навіть принесло мені роботу.

Спікер не образиться, якщо ви не прийдете на його доповідь (хіба скажете йому це в очі). Ба більше, я й сам відвідую від сили третину виступів своїх колег (включно зі своїм, свій ще жодного разу не пропускав). А решту часу — спілкуюсь, тусуюсь, обношу будки, з радістю фоткаюсь з учасниками.

До речі, ніколи не соромтесь зловити спікера й поставити питання (ну хіба він стрімко мчить до вбиральні й уже по виду ясно, що тисне на очі). Ми для того й виступаємо — щоб зацікавити. Якщо щось незрозуміло, або маєш свою точку зору — навіть протилежну — спікер з радістю приділить тобі хвильку.

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

Жартую (чи ні). Беріть від таких подій максимум: дізнавайтесь нове, знайомтесь, тусіть — і, по можливості, завжди потрапляйте на неофіційні пре- та афтепаті (але носіть із собою бетаргін).

Хто з вас був на моїй доповіді на DOU Day? Діліться відгуками в коментарях!

@babichdev

***
До речі, вже цієї суботи я виступатиму на JavaScript fwdays’25, і у вас є шанс виграти один із двох квитків на цю подію. Що треба зробити? Задонатити від 100 гривень та покластися на удачу!
51🔥21👏4
Чи готові ви читати серії пов'язаних постів протягом, наприклад, кількох тижнів, замість різних "випадкових" фактів, чи вам краще таке прочитати за один раз у вигляді великої статті?
(хочу розповісти про Goog Enough Code, тему мого иступу на DOU Day)
Anonymous Poll
80%
Так
13%
Так, якщо пости не поспіль
7%
Ні
8
Good Enough Code. ч.1
Код на відчепись, чи відчепіться від мого коду?


У кожного був цей момент: задачу закрито, ревʼю пройдено, усе працює — але щось свербить. Може, ще трохи підчистити? Перейменувати функцію? Винести шматок у модуль? Просто, щоб було "красивіше".

Так ось це і є зіткнення перфекціонізму з "достатністю" — і саме тут починається наша розмова про Good Enough Code.

Good Enough Code — це не "аби працювало". Це не код "на відчепись". Це підхід, у якому рішення достатньо хороше, щоб працювати, не створювати надмірний технічний борг і не витрачати зайві дні на причесування уже робочого коду. Це про точку, за якою зусилля на покращення вже не виправдані вигодою.

У реальності більшість задач — це не архітектурні шедеври, а практичні компроміси. І намагання зробити "ідеально" часто шкодить більше, ніж допомагає. Час іде на дрібниці, фідбек затримується, команда буксує в ревʼю. Продукт стоїть. Користувач чекає.

Парадоксально, але заради якості ми нерідко жертвуємо користю. І саме підхід GEC повертає фокус туди, де він має бути — на цінність.

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

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

Бо в щоденній розробці виграє не той, хто пише красиво. А той, хто доставляє результат — і вміє вчасно зупинитись.

Зацікавило? Тоді ставте вподобайки і діліться з друзями!


І якщо цей допис набере понад 150 реакцій та 1000 переглядів, то у наступних дописах ми з вами обовʼязково розглянемо:
– Як відрізнити достатній код від халтури?
– Які критерії “good enough”?
– Чому перфекціонізм — це теж технічний борг?
– Як впровадити цей підхід у команду й не перетворити все на безконтрольну лінь?


#good_enough_code #мислення_розробника

100 гривень на РЕБ — квиток на fwdays

@babichdev
200🔥49🤔4👏3
Друзі, у вас лишається лише доба на те, аби взяти участь у розіграші одного з двох Full Ticket квитків на JavaScript fwdays'25!

Усе, що треба — просто долучитися до збору на РЕБ для в/ч А3892.

Кожні 100 грн — ще один шанс виграти.
Фінальна ціль — 260 000 грн.

Посилання на банку
https://send.monobank.ua/jar/ABkKH6rr3u

Номер картки банки
4441111125077309

Переможців обиратиму уже завтра, 21 травня, рандомом від monobank.

@babichdev
🔥9
То null це обʼєкт чи не обʼєкт?!
Певен, ви не раз натрапляли на чергову добірку "приколів" в дусі "ха-ха, JavaScript тупий", в якій точно була згадка про те, що typeof null === 'object'. Хоча насправді null не object. Правда, тупо?

На перший погляд. Але якщо копнути глибше, виявиться, що null це null, а причина такої поведінки typeof захована у глибині віків.

У ранній реалізації JavaScript оператор typeof не мав окремої перевірки на null. Він просто дивився: чи значення схоже на обʼєкт — тобто, чи є посиланням у памʼяті (pointer). А null тоді представлявся як 0x00 — класичний null pointer. Не буквальний, як у C, але концептуально споріднений: “порожнє місце”, що колись мало би бути посиланням.

І через те, що typeof не заглиблювався в перевірку, а лише умовно питав: «Чи це посилання?», то 0x00 сприймалося як “так” — і typeof null повертав "object".

Цю поведінку закріпили в ECMA-262, і пізніше вже не змогли виправити — занадто багато коду залежало від цього “багу”. А Брендан Айк прямо назвав таку поведінку помилкою: (1)

I said typeof null == “object” was a mistake because code that condition guards must null-test before dereferencing


***
Ну а тепер — “ок, а нашо це нам?”. А ось навіщо: ця поведінка лишається актуальною. І банальна перевірка:
if (typeof x === 'object') {
x.foo();
}


…пропустить null. І при звертанні до foo зловите класичний Uncaught TypeError: Cannot read properties of null.

Тому при перевірці на обʼєкт варто додавати й перевірку на "не null":
typeof x === 'object' && x !== null


Ось такий цікавий "баг"-стандарт, що старіший за більшість сучасних веброзробників.

А ви стикалися з ним на практиці? Скільки ночей коштував вам пошук, чому код постійно падає від "Uncaught TypeError…"? Діліться в коментарях!

P.S. Так, так я знаю про оператор ?. і сам активно ним користуюсь. От набере цей допис 101 вподобайку, тоді й розглянемо, чи є цей оператор панацеєю від усіх null.

***
Останній шанс виграти один з двох Full Ticket квитків на JS fwdays'25! Долучайся, донать 100 гривень і вигравай!

@babichdev
155🔥31🤔7👏5
Вітаю переможців розіграшу!

А також дякую усім, хто долучилися до цього збору. Разом ми зібрали 22 728 гривень!

Дякую ще раз, і до зустрічі уже цієї суботи!

З переможцями звʼяжусь щойно отримаю контакти.
24