Каждый язык программирования имеет свои особенности, преимущества и недостатки. JavaScript, в частности, завоевал репутацию благодаря своим особенностям и неожиданному поведению. Если вы долгое время работали в одной среде, вы можете не осознавать, насколько странными могут показаться определенные инструменты или практики разработчикам с другим опытом.
Что делает языки программирования интригующими, так это то, что они предлагают различные подходы к решению проблем, часто со своими уникальными особенностями. Хотя достижение одинаковых результатов на разных языках возможно, путь к достижению этих результатов иногда может быть довольно необычным и неожиданным. Это разнообразие подходов стимулирует инновации и позволяет разработчикам выбирать язык, который лучше всего соответствует их конкретным потребностям и предпочтениям. Вот почему считается хорошей практикой ознакомиться с другими языками программирования и стать «программирующим полиглотом». Расширение ваших знаний за пределы одного языка дает вам свежий взгляд и открывает ваш разум для различных подходов. Это позволяет вам решать общие задачи с разных точек зрения и расширяет ваше понимание концепций программирования. Если вы станете полиглотом в области программирования, это улучшит ваши навыки решения проблем и сделает вас более универсальным разработчиком.
В этой статье мы рассмотрим некоторые странные аспекты JavaScript, которые часто заставляют разработчиков ломать голову.
Давайте проверим некоторые из этих диких и странных примеров:
1. Сравнение трех чисел:
1 < 2 < 3; // -> true 3 > 2 > 1; // -> false
Хм? Разберем каждое выражение:
1. `1 < 2 < 3;` • The comparison 1 < 2 evaluates to true. • In the second part of the expression, true is treated as the number 1. • Therefore, true < 3 is equivalent to 1 < 3, which evaluates to true. 2 . `3 > 2 > 1;` • The comparison 3 > 2 evaluates to true. • True is treated as the number 1 in the next comparison. • Hence, true > 1 is equivalent to 1 > 1, which evaluates to false.
Неожиданное поведение возникает из-за того, что JavaScript не выполняет цепных сравнений, как мы могли бы интуитивно ожидать. Вместо этого он оценивает каждое сравнение независимо и выполняет неявное приведение типов.
Чтобы получить желаемый результат, когда все сравнения оцениваются правильно, мы можем использовать оператор больше или равно (›=): 3 > 2 >= 1;
2. Оператор равенства (==) и оператор строгого равенства (===) в JavaScript:
true == 1; // -> true true === 1; // -> fasle
Оператор равенства (==) выполняет приведение типов, приводя операнды к общему типу перед сравнением. В true == 1
они считаются равными, потому что оба являются истинными значениями.
Оператор строгого равенства (===) не выполняет приведение типов. В true === 1
они имеют разные типы, поэтому возвращает false.
Некоторые другие примеры:
"5" == 5; // true "5" === 5; // false "" == false; // true "" === false; // false
Обычно рекомендуется использовать оператор строгого равенства (===), чтобы избежать неожиданного поведения, вызванного приведением типа.
3. Тайна parseInt():
parseInt(0.5); // -> 0 parseInt(0.05); // -> 0 parseInt(0.005); // -> 0 parseInt(0.0005); // -> 0 parseInt(0.00005); // -> 0 parseInt(0.000005); // -> 0 parseInt(0.0000005); // -> 5
Функция parseInt()
в JavaScript используется для преобразования строк в целые числа. Однако при синтаксическом анализе десятичных чисел с ведущими нулями, например 0,05 или 0,0005, функция возвращает 0. Такое поведение вызвано тем, как parseInt()
преобразует десятичные числа в строки и удаляет ведущие нули. Однако, если после запятой стоит ненулевая цифра, например, в «0,0000005», parseInt()
продолжит синтаксический анализ и вернет первую ненулевую цифру.
4. Причуды десятичной арифметики:
0.1 + 0.2 === 0.3; // -> false 0.5 + 0.1 === 0.6; // -> true
Обработка чисел с плавающей запятой в JavaScript может привести к неожиданным результатам. Например, при сложении 0,2 и 0,1 вместо 0,3 может получиться 0,300000000000000004 из-за проблем с точностью. Сравнения, включающие числа с плавающей запятой, должны выполняться с допустимым уровнем для учета этих несоответствий.
Вы можете прочитать гораздо более подробную статью здесь Понимание странных десятичных вычислений в JavaScript
5. Загадка NaN:
typeof NaN; // -> number NaN === NaN; // -> false
Подождите секунду, Not a Number — это «число»?
NaN
— это специальное значение в JavaScript, представляющее неопределенное или неопределенное числовое значение. Удивительно, но NaN
само по себе считается числовым значением. При сравнении NaN
с другим NaN
с помощью оператора строгого равенства (===) результат будет ложным. Это связано с тем, что NaN
представляет неопределенное значение и не имеет четко определенного сравнения на равенство.
6. Странный способ написать текст:
("b" + "a" + +"a" + "a").toLowerCase(); // -> "banana"
Разберем пошагово:
- «b» + «a»: строки «b» и «a» объединяются, в результате чего получается строка «ba».
- +’a’: выражение +’a’ пытается преобразовать строку ‘a’ в числовое значение с помощью унарного оператора плюс (+). Поскольку «а» нельзя преобразовать в число, оно оценивается как NaN (не число).
- «ba» + NaN + «a»: при объединении строки «ba» с NaN JavaScript преобразует NaN в строку «NaN». Результат конкатенации становится «baNaNa».
- («baNaNa»).toLowerCase(): метод toLowerCase() вызывается для строки «baNaNa», преобразуя ее в нижний регистр. Конечным результатом является строка «банан».
Вот еще пример с пояснением:
'H' + // 'H' ([] + {})[+!![] + [+!![]]] + // 'e' == '[object Object]'[11] (![] + [])[!+[] + !![]] + // 'l' == 'false'[2] (![] + [])[!+[] + !![]] + // 'l' == 'false'[2] ([] + {})[+!![]] + // 'o' == '[object Object]'[1] (+{} + {})[+!![] + [+[]]] + // ' ' == ('NaN' + '[object Object]')[10] 'W' + // 'W' ([] + {})[+!![]] + // 'o' == '[object Object]'[1] (!![] + [])[+!![]] + // 'r' == 'true'[1] (![] + [])[!+[] + !![]] + // 'l' == 'false'[2] ([][[]] + [])[!+[] + !![]] + // 'd' == 'undefined'[2] '!' // '!' // -> 'Hello World!'
Фрагмент кода демонстрирует творческое использование операторов JavaScript и преобразования типов для извлечения символов и формирования строки «Hello World!». Он демонстрирует гибкость и изобретательность программирования на JavaScript, где нетрадиционные подходы могут дать интригующие результаты.
Вот действительно классный и забавный инструмент, который поможет вам Написать предложение, не используя алфавит.
Бонус.
Комментарии HTML как комментарии JavaScript:
// valid comment <!-- valid comment too
Интересная историческая причуда заключается в том, что синтаксис <!-- -->
, обычно используемый для комментариев HTML, также считается допустимым комментарием в JavaScript. JavaScript обрабатывает его как однострочный комментарий, игнорируя все, что находится между разделителями <!--
и -->
. Хотя это технически возможно, использование HTML-комментариев в коде JavaScript, как правило, не рекомендуется, поскольку это может привести к путанице и ухудшить читаемость кода, если он отделен от контекста HTML.
Заключение.
Причуды и сюрпризы JavaScript могут как разочаровать, так и позабавить разработчиков. Понимая и признавая эти особенности, вы сможете более эффективно ориентироваться в особенностях языка. Важно знать об этих причудах, несмотря на то, что вы можете никогда не встретить их в реальной жизни. Универсальность и широкое распространение JavaScript делают важным понимать его нюансы, оставаясь при этом в курсе лучших практик. Итак, вперед и примите странности JavaScript — это часть того, что делает программирование захватывающим и постоянно развивающимся путешествием.
Дополнительные ресурсы:
Обязательно попробуйте эту веселую викторину, вам будут показаны 25 причудливых выражений, и вам нужно будет угадать результат. Каков ваш счет? Мне было стыдно 11)
Гораздо более широкий список забавных и хитрых примеров JavaScript здесь Что за хрень JavaScript?
JavaScript — это странно — видео с пояснениями.