2016-12-24 5 views
2

NaN - одна из тех рудиментарных реализаций сомнительного происхождения, но по большей части Я получаю это. Тем не менее, я напечатал это в Узла строку сегодня и не мог понять его ...Почему NaN =! NaN верны?

NaN = !NaN 
> true 

Является ли это просто возвращением оценочного результата !NaN? Это имеет смысл, но я удивлен, что при попытке назначить NaN другому значению ошибки нет.

Примечание: Этот вопрос касается этой конкретной структуры синтаксиса; есть много вопросов, связанных с NaN и isNaN, но я не мог найти ответ после поиска в Google. Спасибо Ори Дрири за best answer thus far.

console.log(NaN = !NaN);

+1

@pvg не похоже на дубликат этого. Никакого сравнения NaN с чем-либо здесь нет. –

+1

@pvg Я искал, прежде чем публиковать это и не видел ответа на конкретный вопрос, который я задавал. – newswim

+2

@MartinSmith вы правы, я неправильно понял вопрос, удалил флаг. Это намного проще, но сложнее прикрепить обман в море связанных ответов. – pvg

ответ

9

Вы присваивающей true в NaN вместо сравнения NaN к !NaN с использованием === или ==, поэтому операция возвращает присвоенное значение ->true. Javascript игнорирует это назначение молча, потому что NaN is read only.

console.log(NaN = true); 
 

 
// NaN hasn't changed 
 
console.log(NaN);

Если вы добавите use strict в код, JS выдаст ошибку read only вместо:

'use strict'; 
 
NaN = true;

+0

Отличный ответ, спасибо! Еще одна причина, по которой я должен использовать Strict Mode. – newswim

+0

Строгие режимы режима :) –

1

Использование = оператора, вы назначаете значение переменной , Однако то, что вы не знаете, это делает это, оно возвращает значение того, что назначается. Typing:

v = 1 

в JavaScript РЕПЛ будет отображать 1, потому что это то, что было поручено v. Таким образом, выполнив:

NaN = !NaN 

присвоит противоположное значение NaN к NaN сам. С NaN в boolean находится false, затем !NaN в булевом должно быть true.

1

Javascript действительно странно: Когда вы пишете

NaN = true // true 

который вы в основном делаете в вашем заявлении, вы получите «истинный». Это то же поведение, что и при написании

a = true // true 

, где возвращается правая часть задания. Но если вы добавите var и напишите

var a = true // undefined 

тогда ничего не возвращается. Кроме того, если заменить NaN с выражением, которое имеет значение NaN, например

1/"a" = true // error! 

тогда вы получите ReferenceError. Я рекомендую никогда не использовать возвращаемые значения присвоений. Поведение неубедительно, и ваш код будет трудно читать. Вы можете включить «строгий режим», чтобы проверить это для вас.

+0

Ницца! Спасибо за разъяснение! – newswim

2

Попробуйте запустить Javascript в режиме strict, чтобы избежать большинства проблем.

NaN, нуль, ложь "", нулевой, не определено, 0 и т.д., они рассматриваются как falsy ценности (помните falsy! == false) в JavaScript, независимо вы используете режим strict или нет.

// 'use strict'; 

console.log(!NaN);  // true 
console.log(!null);  // true 
console.log(!false);  // true 
console.log(!"");  // true 
console.log(!null);  // true 
console.log(!undefined); // true 
console.log(!0);   // true 

Это правда и в Python, за исключением NaN. Например,

print(not False)  # True 
print(not None)   # True 
print(not float("NaN")) # False 
print(not "")   # True 
print(not 0)   # True 

Источник путаницы Когда мы используем несколько языков, иногда это может быть источником путаницы.

Например,

В Python 'cat' in ['fat', 'cat', 'rat', 'hat'] возвращает True.

В Javascript 'cat' in ['fat', 'cat', 'rat', 'hat'] (точно такая же часть кода) возвращает false, независимо от того, используете ли вы режим strict или нет.

В Python print(not []) возвращает значение True.

В Javascript console.log(![]); возвращает false.

Это одна из причин, почему я всегда люблю использовать отладчики, REPL и т. Д. Независимо от того, насколько прост в коде.