Алгоритм JavaScript может быть «непредсказуемым»!

Как обрабатывать угловые случаи сравнения?

Поймайте все эти случаи и начните писать первоклассный код!

«Любая достаточно продвинутая технология неотличима от магии».

- Артур Кларк (третий закон Кларка)

Прежде чем мы начнем знакомиться с угловыми случаями JavaScript, я хотел бы провести различие между угловым регистром и крайним случаем.

Можно сказать, что Edge Case - это проблема, которая может возникнуть только при минимальных или максимальных параметрах. Прогнозирование может оказаться сложной задачей, поскольку такими ситуациями можно пренебречь или недооценить. Например, ПК на полной мощности может перегреться, и его производительность может немного ухудшиться.

Я также хотел бы представить пограничный случай (тоже предмет сомнения). Это может произойти, если один из параметров выходит за минимальные или максимальные пределы.

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

Вы не поверите!

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

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

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

В следующем примере я подробно объясню, что происходит, чтобы у вас было четкое представление о том, что делает алгоритм:

Во-первых, обратимся к документации. В строке 6 у нас есть сравнение примитивного и непримитивного значения. В данном случае действует правило №11. Результатом этого алгоритма является пустая строка.

На следующем этапе мы сравниваем пустую строку с false. По алгоритму применяется правило №9. Следующим шагом (строка 8) является применение правила №5. Пятый шаг - сравнить два числа. Поскольку мы используем сравнение на равенство, мы будем вызывать алгоритм строгого сравнения на равенство.

Последний шаг - вернуть true из строгого сравнения на равенство. Второй пример более практичен, потому что мы используем не равно (отрицание двойного равенства) - проверка, не равно ли принудительно:

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

Не связывайтесь с логическими значениями

Давайте поговорим о логических значениях и их связи с абстрактным равенством. Это то, с чем вы много работаете. Мы должны взглянуть на возможные случаи:

Явность иногда может вызвать ненужные проблемы. Во втором предложении if мы сравниваем массив с логическим значением. Вы могли подумать, что результатом этой операции будет логическое значение true, но это не так. Тот же эффект будет при строгом равенстве.

Сравнение массива и логического значения будет проходить во многих случаях. Прежде чем мы рассмотрим примеры, я дам вам подсказку: Никогда не используйте двойное равенство с логическими (true и false) . Разберем, как работает алгоритм:

Первое предложение if говорит само за себя, поэтому я не буду тратить время на объяснения. Как и в предыдущем примере, я ссылаюсь на документацию. Сравнение массива и логического значения вызовет абстрактную операцию ToPrimitive () (правило №11), поскольку одно из сравниваемых значений является непримитивным типом.

Следующие три шага просты. Сначала преобразуем логическое значение в число (правило №9: ToNumber (true)), на следующем шаге строка становится числом (правило №5: ToNumber (« ) »), а последним шагом является выполнение строгого сравнения на равенство. Третий пункт такой же, как и предыдущий.

Одним из недостатков принуждения является абстрактная операция ToNumber (). Я не уверен, что преобразование пустой строки в число должно вернуть 0. Было бы гораздо лучше вернуть NaN, поскольку NaN представляет недопустимое число.

Вывод: Бессмысленный ввод всегда дает бессмысленный вывод. Нам не нужно все время говорить откровенно. Иногда неявно может быть лучше, чем явно.

Лучшее, что вы можете сделать, проверяя наличие значений в массиве, - это быть более явным и проверить наличие .length, чтобы убедиться, что это строка или массив:

Глубокая проверка более надежна. Как видите, пустой массив вернет true (после логического принуждения). То же самое и с объектами - всегда проводить тщательную проверку. Убедившись, что тип является строкой или массивом, мы будем использовать оператор typeof (или метод Array.isArray()).

Разъяснение

Есть рекомендации, которым вы должны следовать, чтобы не попасть в ловушку угловых дел. Использование двойного равенства везде может быть палкой о двух концах. Имейте в виду, что использование двойного равенства, когда обе стороны сравниваемых значений равны 0, пустая строка или строка только с пробелами - плохая практика.

Следующая важная вещь, которую следует запомнить, - избегать использования двойных равных с непримитивными типами. Единственный раз, когда вы можете использовать его, - это сравнение идентичности. Я не могу сказать, что это на 100% безопасно, поскольку он достаточно близок к крайнему случаю, и это того не стоит.

ECMAScript 6 представил новую утилиту Object.is (). С помощью этого метода мы наконец можем выполнить сравнение идентичности без риска побочных эффектов. В конце концов, мы можем сказать, что использование double equals безопасно только с примитивными типами, но не с непримитивными.

И последнее, но не менее важное: избегать использования двойного равенства с логическими значениями (true и false). Намного лучше разрешить неявное логическое принуждение (вызвать абстрактную операцию ToBoolean ()). Если вы не можете включить неявное принуждение и можете использовать двойное равенство с логическими значениями (true и false), то используйте тройное равенство.

Вывод: В большинстве случаев угловых случаев можно избежать путем рефакторинга нашей кодовой базы.