Странный код в источниках 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");
}
}