Привет! Сегодня мы собираемся обсудить 10 аномалий JavaScript, результаты которых никак нельзя было ожидать в обычном режиме. Эти случаи называются крайними случаями, поскольку они слишком далеки от основной логики. Давайте начнем!
Внимание! Эти кейсы часто задают во время собеседований;)
1. 0,1 + 0,2 === 0,3 // ложь
Что ж, это настоящий крайний случай, потому что никто не может четко определить, почему это так. Это один из побочных эффектов работы с двоичными числами с плавающей запятой. Это верно для всех языков, использующих IEEE 754, и не имеет прямого отношения к JavaScript.
0.1 + 0.3 === 0.4 //true 0.5 + 0.2 === 0.7 //true 0.4 + 0.5 === 0.9 //true ... 0.1 + 0.2 === 0.3 // false, whaaat? 0.1 + 0.7 === 0.8 // false, huh...
Пояснение: Фактически, 0,1 + 0,2 примерно равно 0,30000000000000004… и 0,1 + 0,7 равно ~ 0,7999999999999999 на основе стандартов IEEE 754.
Просто будьте внимательны при использовании чисел с плавающей запятой, и вы можете найти решение для этого на посте Yerevancoder.
2. 4 - «- 4» === 8 // верно
Если у нас есть 4 + '-4'
, мы получим '4-4'
. Поскольку число 4 просто меняет свой тип для объединения в виде строк. Однако этого не произойдет с -
, поскольку для строк нет такой операции. Таким образом, строка изменит свой тип на число, потому что вычитание - это операция, зависящая от числа. Та-да-да-даам! У нас получилось 8. Это эффект приведения или приведения типов в JavaScript.
3. {} + [] === 0 // верно
Это должно полностью поразить вас. :)) Это может стать еще интереснее, если я скажу, что [] + {} === 0 => false
.
Объяснение. Давайте рассмотрим первый случай.
{}
распознается как область видимости блока, а не как объект, что означает, что он просто входит в область и выходит из нее. Затем у нас остается+ []
, который меняет тип всего, что следует за+
, на число. Итак, мы получили это{} + [] === 0
. Почему не то же самое, когда мы меняем их местами? Итак,{}
в этом случае считается объектом, и обе стороны преобразуются в примитивы, что вызываетtoString()
метод, и мы получаем"" + "[object Object]" = "[object Object]"
.
4. a ==! A // верно
У нас есть следующее.
let a = [];
Как вы, наверное, уже знаете, двойной знак равенства служит лишь поверхностным сравнением. Он приводит к типу, пока не получит тот же тип.
Объяснение: В этом случае переменная
a
имеет ссылку на пустой массив. И!a
имеет значениеfalse
, поскольку операция!
изменяет тип на логический. Итак, обе стороны принуждены к числам, и обе стороны ложны = ›Number([]) === 0 && Number(false) === 0
. Таким образом, получаем то, что имеем:a == !a
.
5. функция hello возвращает строку, но hello () // не определено
Посмотрите на эту функцию. Каким будет его результат?
function hello() { return "Hi there!"; };
На первый взгляд, это простая функция, возвращающая строку.
Ой! Возвращает undefined
: /
Объяснение. В JS есть функция, называемая автоматической вставкой точки с запятой (ASI), которая в некоторых случаях автоматически добавляет точку с запятой в конце строки и отделяет ее от продолжения. Вот почему во многих случаях ставить точку с запятой в JS необязательно. Но иногда это может привести к проблемам. Это как раз тот случай. Он ставит точку с запятой после return и становится
return;
, что означает return undefined. Чтобы исправить это, вы должны переместить строку в ту же строку или добавить круглые скобки, как показано ниже.
function hello() { return( "Hi there!" ); };
P.S. В следующей статье вы найдете более интересные крайние случаи с более подробными объяснениями! Это конспекты моей лекции Случаи использования JS Edge. Https://yerevancoder.com/2018-03-06-javascript-edge-cases/
P.P.S. Большое спасибо Эдгару Ханзадяну за его помощь в составлении подробных конспектов лекций.