Как перехитрить угловые случаи JavaScript

Что такое отрицательный ноль?

Отрицательного нуля не существует!

Это будет ответ, когда вы спросите математика о существовании отрицательного нуля. Итак, какого черта отрицательный ноль? Что бы об этом подумал Исаак Ньютон? Что ж, мы не можем его спросить, но мы можем прочитать спецификации! Если мы проверим IEEE 754 (2019 - Стандарт IEEE для арифметики с плавающей запятой), мы сможем найти некоторую полезную информацию об отрицательном нуле. Согласно спецификациям, отрицательный ноль - это нулевое значение со знаком - перед ним - отрицательное представление нуля. Было ли отрицательное значение нуля ошибкой? Нет, причины выясним чуть позже. Давайте воспользуемся нашими знаниями, чтобы проверить:

Например, если мы присвоим -0 переменной, а затем протестируем ее с тройным равенством (===), она вернет истину - ожидаемый результат, верно? Да, но что произойдет, если мы пытаемся преобразовать значение в строку (преобразовать ее в строку)? Давай попробуем:

Мы использовали здесь метод toString и получили ожидаемый результат. Это нехорошо, где знак? Вы можете предсказать это? Как и в других случаях, главное - это исторические причины. На заре разработки языка разработчик JavaScript думал, что это будет выглядеть как ошибка, поэтому они решили поставить «0» вместо «-0».

Вывод: Язык программирования должен делать значимые вещи, а не то, чего хотят разработчики!

Еще одна популярная функция - это ленивая точка с запятой (автоматическая точка с запятой в конце выражения) - модная штука. В этом нет необходимости, просто позвольте разработчикам делать свою работу. Давайте воспользуемся некоторыми математическими функциями, чтобы проверить эту странность:

Что вы должны думать об отрицательном нуле сейчас? Не число, правда? Нет, в этом случае лгут операторы меньше и больше чем.

ECMAScript 6 представил новую сверхразумную утилиту - Object.is () (Кайл Симпсон называет это четырехкратным равенством). С помощью этой утилиты вы, наконец, можете определить, являются ли два значения одним и тем же значением. Раньше не существовало встроенного (собственного) метода для этого. Взгляните на следующий пример:

Почему бы нам не попробовать с помощью Number ():

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

Я много говорил об исторических фактах, маленьких и больших ошибках, но в чем смысл отрицательного нуля? Как мы можем использовать эту странную вещь?

В математике обычно используются возможные значения в качестве результата - отрицательное и положительное представление одного и того же значения. В математике обычно используются два возможных значения. У вас может быть отрицательное и положительное представление о ценности - это обычная практика, когда мы говорим о квадратных уравнениях. Следующий вопрос очень важный! Какое единственное число не может иметь двойного представления одного и того же значения? Конечно, это ноль.

В программировании дело обстоит иначе. Как тогда использовать отрицательный ноль? Приведу простой пример. У нас есть предмет, который можно перемещать вперед и назад. Движение вперед более распространено, но мы должны справляться с движением в противоположном направлении. Мы собираемся добавить - подпишите перед значением, и дело решено! Да, а как же угловой корпус - ноль? Спасибо разработчикам JavaScript за ОТРИЦАТЕЛЬНЫЙ НУЛЬ. Когда значение равно нулю, мы все еще можем представить направление движения с помощью отрицательного нуля. Как видите, в некоторых случаях может быть полезен отрицательный ноль! Элемент может представлять что угодно: AI, GPS и т. Д.

Взгляните на следующую иллюстрацию, чтобы прояснить ситуацию:

Еще один реальный пример - биржа! Очень полезно использовать отрицательный ноль для реализации курса биржевого тренда. С помощью этой функции мы можем различать положительный и отрицательный тренд:

Эта функция представляет собой простой пример трекера, который мы используем для обмена на складе. Мы можем отслеживать эти тенденции и их взлеты и падения… С помощью этой супер-крутой нулевой отрицательной функции мы можем представить тенденцию, даже если она равна нулю в данный момент (-0 для падения, 0 для роста).

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

У математики есть свои оговорки!

Мы можем знать только то, что ничего не знаем!

Это была известная цитата, первоначально написанная Львом Толстым. Математика - прекрасная наука, но не программирование!

Какие вопросы вы задаете себе сейчас? Чтобы прояснить ситуацию, приведу пример:

Он вернет 1 для положительного значения и -1, если значение отрицательное. Эти результаты с 1 и -1 могут быть непростыми, но этому есть историческая причина. Была заимствована практика - из массивов. Философия массива проста: если он не содержит значения, он вернет -1. Вот пример:

В программировании 40 лет назад все было по-другому. Единственный способ описать что-то - использовать числа. Единственным разумным способом обозначить несуществование было использование -1. ​​ Создатель JavaScript нашел лучшее решение для решения этой проблемы. К сожалению, он придерживался старой школы. Разве не разумнее вернуть NaN (недопустимое представление числа) вместо -1?

Это было немного из истории JS. Теперь мы вернемся к нашему сеансу. Object.is () должен сообщить нам, был ли у нас отрицательный ноль, но:

Это правда? Почему они это делают? Этому нет разумного объяснения. Самый простой способ - вернуть 1 (или -1), как в первом примере. Эта утилита была многообещающей, но в итоге нас разочаровала.

К счастью, у JavaScript есть сильное сообщество, и они нашли решение этой проблемы. Мы можем «исправить» этот метод, чтобы он вел себя более разумно:

Если аргумент не имеет нулевого значения (0 или -0), мы будем использовать встроенный Math.sign (). Если аргумент имеет нулевое значение (0, -0), мы будем использовать Object.is для сравнения. Давайте проверим это:

Мы также можем изменить этот метод на объекте-прототипе:

Имейте в виду, что ECMAScript Standard не рекомендует изменять цепочку прототипов.

Вывод: Math.sign () не поможет нам определить отрицательный ноль. Чтобы различать 0 и -0, напишите свой собственный метод sign ().

Это были некоторые частные случаи, с которыми мы часто сталкивались. Нам не нужно избегать этого, мы можем заставить его поступать правильно. В программах будут особые ценности. Наша цель - понять их и правильно использовать. Хороший подход поможет нам сделать наш код более читабельным, семантическим, а главное - понятным.

Примечание от Plain English

Вы знали, что мы запустили канал на YouTube? Каждое видео, которое мы снимаем, будет направлено на то, чтобы научить вас чему-то новому. Проверьте нас, нажав здесь, и обязательно подпишитесь на канал 😎