Странный код в источниках jQuery: var! == var? x: y;

Недавно я нашел одну странную строку в источниках jQuery (последняя версия 1.9.1, пакет Sizzle, строка 129 funescape):

funescape = function( _, escaped ) {
    var high = "0x" + escaped - 0x10000;
    // NaN means non-codepoint
    return high !== high ?            // <--- LINE 129
        escaped :
        // BMP codepoint
        high < 0 ?
            String.fromCharCode( high + 0x10000 ) :
            // Supplemental Plane codepoint (surrogate pair)
            String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
};

В чем причина сравнения high !== high? Очевидно, что return escaped никогда не будет выполнен. Или мне что-то не хватает?

Ссылка: https://github.com/jquery/sizzle/blob/master/sizzle.js#L129

Ответ 1

Фактически это написано в комментарии прямо выше:

//NaN означает некодирование

Итак, сначала необходимо выполнить это сравнение для обработки события NaN, как в JavaScript:

NaN === NaN возвращает false.

Как указано Джеймсом Уайзманом, также важно знать, почему разработчик использовал high !== high вместо isNaN(high), который был бы более ясным.

Это, безусловно, основано на производительности. Этот тест показывает, что a !== a в двадцать раз быстрее, чем isNaN(a).

zzzzBov также указывает, что isNaN() можно перезаписать, использование !== также более переносимо.

Дополнительная информация от Бенджамин Груэнбаум:

Также стоит отметить, что NaN не соответствует чему-либо еще, поскольку ну, а также он не равен чему-либо еще в нестрогом смысле

И из Ян Дворжак:

Также обратите внимание, что {valueOf:function(){return{}}} делает сам

Ответ 2

Условие high !== high возвращает true, когда high NaN. Интересно, почему ребята jQuery не использовали гораздо более четкую функцию isNaN(high), но это, вероятно, было связано с соображениями производительности, как указывал коопаха.

NaN (N ot- a - N umber) означает результат, который не может быть представлен как Number. Это неопределенное число.


Почему NaN === NaN возвращает false?

Рассмотрим

0/0          = NaN
Math.asin(2) = NaN

Вы знаете, что 0/0 отличается от Math.asin(2), поэтому почему бы NaN было равно NaN?

Ответ 3

Я поддерживаю некоторые комментарии здесь, но думаю, что это достойная информация.

Некоторые комментарии к исходному вопросу предположили, что этот метод проверки для NaN на самом деле намного быстрее, чем isNaN()

При использовании в сочетании со следующей альтернативой parseInt parseFloat мы имеем очень быстрый способ преобразования в число и проверки его числового состояния.

Является ли Subtracting Zero какой-то трюк производительности JavaScript?

Итак, вместо

function Translated(val) {
    var x = parseFloat(val);
    if (!isNaN(x)) {
        alert("Not a number");
    }
}

Мы можем иметь

function WTF(val) {
    var x = val - 0;
    if (x !== x) {
        alert("Not a number");
    }
}