dr.Brain

doctor Brain

мир глазами веб-разработчика

JavaScript: 5 странностей

о некоторых особенностях JavaScript, вызывающих нервный смех

dr.Brain

время чтения 3 мин.

Photo by Evan Fitzer on Unsplash

Конечно, мы любим JavaScript. Это великолепный языка программирования. Но у него есть и “веселая” сторона, которая делает этот язык еще более интересным для изучения. В этой статье мы разберем 5 таких примеров.

И это не баги JavaScipt, а его особенности.

baNaNa

Как написать слово “banana”? В JavaScript для этого есть один нетривиальный способ:

let word = 'b' + 'a' + + 'a' + 'a';
console.log(word) // baNaNa

Как это работает?

Выражение 'b' + 'a' + + 'a' + 'a' возвращает baNaNa так как 'b' + 'a' + + 'a' + 'a' преобразуется в 'b' + 'a' (+'a') + 'a', а (+'a') в свою очередь соответствует не-числу NaN. Это, в свою очередь, происходит из-за того, что оператор двоичного сложения пытается преобразовать операнд в число, но символ a числом не является.

Математика логических значений

Итак, от цифр можно сильно устать, но для JavaScript - это не проблема. Всегда можно переключиться на true и false. В это языке программирования логические значения можно использовать для математических вычислений:

true + true; // -> 2
(true + true) * (true + true + true) // -> 6

Как это работает?

Конструктор Number преобразует значения в числа. Таким образом true превращается в 1, а false превращается в 0.

Number(true); // 1
Number(false); // 0

Сходным образом унарный оператор + пытается преобразовать любой операнд в число, в том числе и логические значения true и false.

+true // 1
+false // 0

Наконец, можно сказать, что при сложении или вычитании происходит автоматический вызов метода toNumber, который в соответствии со спецификацией: для аргумента true возвращает 1, а для агрумента false возвращает 0.

Теперь понятно, почему математика с логическими значениями в JavaScript действительно работает?

NaN является числом

Давайте узнаем: какому типу данных в JavaScipt соответствует не-число (not-a-number) NaN:

typeof NaN // 'number'

Действительно?

Как это работает?

Возможно, это покажется странным, но на самом деле NaN является числом и используется в случаях, когда определенное значение не может быть представлено в рамках используемого числового типа. Другими словами, это число, которое не может быть описано.

Доступ к свойствам через массив

Получить доступ к значению по индексу можно, поместив в оператор [] число или строку. Но, также, для этих целей можно использовать и массив:

let data = { number: 1 },
    array = ["number"];

console.log(data[array]); // -> 1

Как это работает?

Это работает, потому что оператор [] всегда запускает метод toString и преобразует аргумент в строку. А в JavaScript приведение массива, состоящего из одного элемента, в строку всегда вернет строку, соответствующую значению первого элемента массива.

Например:

console.log(["test"].toString()); // test

Сортировка

Задача кажется простой: достаточно отсортировать массив числе с помощью метода sort():

[1, 5, 2, 10, 30].sort();

Результат:

[1, 10, 2, 30, 5]

Неужели JavaScript считает, что числа действительно отсортированы?

Как это работает?

И это не баг. По умолчанию метод sort() преобразует элементы массива в строки, после чего сравнивает и сортирует их значения в формате UTF-16. Поэтому, если действительно нужно провести сортировку значений, отличных от string, необходимо передать в метод сортировки функцию сравнения:

console.log([1,5,2,10,30].sort((a, b) => a - b));
// [1, 2, 5, 10, 30]

Спасибо за внимание.


Перевод статьи “5 JavaScript WTFs”.

Новые публикации

Далее

Категории

О нас

Frontend & Backend. Статьи, обзоры, заметки, код, уроки.