Привет! Сегодня мы собираемся обсудить 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. Большое спасибо Эдгару Ханзадяну за его помощь в составлении подробных конспектов лекций.