5 хибних уявлень про JS, від яких може боліти голова

💡 Усі статті, обговорення, новини про Front-end — в одному місці. Приєднуйтесь до Front-end спільноти!

Було у вас таке, що ви ніяк не можете зрозуміти, звідки взявся той 0 в розмітці? Чи перебираєте ключі обʼєкта, а воно видає вам ще якісь ліві значення? Тупий JS? Чи усе-таки ви стали жертвою хибних уявлень про JS, які часто призводять до дрібних, але противних багів? Давайте глянемо до дрібниць, які ми усі забуваємо по різному, але страждаємо ми від того однаково:

a && b() це те саме, що й if (a) b()

З цим ви точно стикались — a && b() часто використовують
як скорочену форму if (a) b() через подібність результату
в більшості випадків.

Однак вони працюють по-різному. Логічний оператор && перевіряє операнди зліва направо та виконує наступний операнд лише тоді,
коли попередній є truthy.

Він зупиняється при першому falsy значенні, повертаючи його,
або, якщо всі операнди truthy, повертає значення
останнього операнду.

Object.assign створює повну копію обʼєкта

Object.assign створює поверхневу копію (shallow copy), тобто копіює лише верхній рівень
властивостей об’єкта.

Якщо об’єкт містить вкладені об’єкти або масиви, вони копіюються за посиланням,
а не створюються заново.

Коли ж вкладених структур немає, результат дійсно буде схожий на повну копію.

for...in перебирає тільки власні властивості обʼєкта

Цикл for...in перебирає усі перелічувані (enumerable) властивості, включаючи успадковані від прототипу.

Якщо об’єкт має властивості
в прототипному ланцюжку, вони також будуть перебрані.

Якщо потрібно перебрати тільки власні властивості, необхідно використовувати методи, такі
як Object.hasOwnProperty()
або Object.keys()

[].length завжди показує кількість елементів у масиві

Насправді властивість length показує найбільший індекс + 1,
але не обов’язково фактичну кількість елементів у масиві.
Якщо масив містить «дірки» (порожні елементи), вони
не враховуються
як реальні елементи.

Також значення length можна змінити вручну, що може призвести до втрати елементів або створення «дір».

console.log виводить «зліпок» обʼєкта на момент виклику

console.log виводить посилання
на об’єкт, а не його поточний стан на момент виклику.

Якщо об’єкт змінюється після виклику console.log, в консолі буде відображено оновлені значення при розгортанні.

Щоб отримати «зліпок» (фіксовану копію об’єкта), потрібно серіалізувати його, наприклад, за допомогою JSON.stringify.

***

Дякую за увагу! Сподіваюсь, що вдалося нагадати вам про такі дрібні нюанси, через які можна витратити кілька годин на пошук бага, а тепер ви не будете витрачати кілька годин на пошук бага )

Гарного вам усім дня!

P.S. Автор дуже недоброзичливо ставиться до коментарів російською мовою.

👍ПодобаєтьсяСподобалось13
До обраногоВ обраному4
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

дякс

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

Сергію, будь-ласка, зупиніться. Краще візьміть додаткову задачу на роботі.

Бо це стає схожим на спам. Я розумію коли новачки пишуть подібні статті, для бонусів чи підвищення, але ж Ви вже зріла ті поважна людина.

Яка частота моїх дописів не буде вас засмучувати?

Хотілося б бачити щось дійсно варте уваги. Що змусило Вас написати це?

Шкода. Розгляньте все ж варіант з додатковою роботою.

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

console.log((2 ** 30) / 2); // 536870912
console.log((2 ** 30) >> 1); // 536870912 (good, same result)

console.log((2 ** 31) / 2); // 1073741824
console.log((2 ** 31) >> 1); // -1073741824 (oopsie)

Будь-які бінарні операції форсять цілі числа в 32 розряди, хоча ці числа в JS 64 розрядні для звичайних арифметичних операцій.

ну блін, за hasOwnProperty кожна дока, кожен індус на медіумі згадує. Як про це можна бути не в курсі.

От як запам’ятати різницю між for...in та for...of — оце дійсно питання.

Я вирішив цю проблему просто — не використовувую for...in )

После того, как узнал, что в js указатель this не обязательно указывает на текущий объект, завязал с javascript. Эта дурь не для меня

Это в котором выполняется код. Мне лень объяснять (да и забыл давно уже эти тонкости), потому просто кидаю ссылку
medium.com/...​n-javascript-34116f1ca5f2

Коментар видалено автором допису.

Не псує життя, але можна забути чи переплутати випадково щось таке:

В JavaScript

[2, 5, 13].sort()
→ Array(3) [ 13, 2, 5 ]

В Python:

print([2, 5, 13].sort())
→ None

О, теж цікава штука, варто в наступну добірку взяти!

Так, є sort(), а є sorted(). :) Гарне питання для співбесіди.

>>> sorted([5, 2, 13])
[2, 5, 13]

Можливо Ви мали на увазі toSorted() ?

Коли я бачу код

expression && console.log("something")

то раджу не змішувати statements та expressions та переробити на if. Тому що якось дивно виглядає expression, результат якого ніяк не використовується. Хочеться, щоб воно було у функціональному стилі. :)

А тут і не змішується стейтмент з експрешином. Те, що ви бачите, це звичайний LogicalANDExpression, який складається з left-hand side expression, токена && та right-hand side expression (в вашому випадку консоль.лог це CallExpression. А можлива така конструкція на голому місці тільки тому, що цей весь експрешн видається за стейтмент на рівні синтаксичного дерева.

Так, я розумію що це call expression.

Але. З точки зору логіки a & b = b & a, що не виконується у прикладі вище. Так, я розумію, що воно обчислюється зліва направо, та оптимізовано не виконувати наступні аргументи, якщо перший false. Так, я розумію що так воно в інших мовах також. Мені не подобається, що порушує правила логіки, та що воно не у функціональному стилі.

Але. З точки зору логіки a & b = b & a, що не виконується у прикладі вище.

Бо a & b = b & a — комутативна операція, а в прикладі коду там запаяний багаторівневий експрешн, який реально повертає значення в кожній своїй гілці (console.log поверне undefined).

Тому в JS не слід шукати логіку))) Мова дизайнилась в ті часи, коли кожен кілобайт трафіку був на вагу золота, тому маємо такі не сильно логічні конструкції, аби тільки зрізати декілька лишніх символів.

Я вам більше того скажу, більшість транспайлерів JS коду та мініфікаторів перетворює конструкції типу `if (a === true) { callMe(1, 2, 3); }` в `!!a && callMe(1, 2, 3)`.

!!a — за це я одразу reject тисну (implicit type cast). :)

null? ’’, 0?
я ще розумію коли цей implicitний тайпкаст десь далі передається, використовується деінде ще. А це ж буквально точкова операція. І всяко набагато краща за проте a && b

Тобто ’!!’ це неявно в булеан, а от специфіка нестрогого порівняння з undefined яке робить не зовсім те це явно...

Якщо навіть це для якогось JS розробника «implicit», то йому краще знайти щось інше комільфове до душі :) Хоча це ж не специфічне для JS...

Треба було в назву «ТЦК» додать

ТЦК та 5 хибних уявлень про JS
Майже Роулінг
Треба провести дослідження, як згадка про цю абревіатуру впливає на кількість коментарів

А які «дрібниці» псували життя і реліз вам?

коли додаєш змінну до рядка, а в тій змінній -null 🤗

Підписатись на коментарі