Разница между Boolan (! X) и Boolean (x == 0)?
Код-фрагмент 1:
if ( !x ) { /* do stuff */ }
Код-фрагмент 2:
if ( x == 0 ) { /* do stuff */ }
Для каких значений x
эти два фрагмента кода отличаются?
Я спрашиваю, потому что, хотя я читал главу в ==
в спецификации, мне все еще трудно справляться с ситуациями, подобными приведенным выше (там, где они объединены с ToBoolean принуждением).
btw, я хочу знать это только ради того, чтобы знать это (я хочу понять язык), поэтому не беспокойтесь, рассказывая мне о ===
или спрашивая меня, что такое x
.
Обновление: Я исправил фрагмент кулака. Я имел в виду !x
.
Ответы
Ответ 1
Следующее даст вам true
для первого и false
для второго фрагмента:
И это даст вам false
для первого и true
для второго фрагмента:
-
[]
- "0" и любая другая строка, которая преобразуется в 0 с помощью
Number(x)
, таких как "00", "000", "+0" и "-0" (которые я теперь буду называть "строк noughty" )
- массив, содержащий один элемент, который является
0
, null
, undefined
или пустая или нулевая строка.
Для всего остального вы получите тот же результат для обоих фрагментов, хотя может быть один или два других случая, о которых я не думал.
Ответ 2
-
[] == 0
истинно; ![]
false
-
null == 0
- false; !null
истинно
-
NaN == 0
- false; !NaN
истинно
-
undefined == 0
- false; !undefined
истинно
!x
проверяет, является ли x
"ложным".
x == 0
будет проверять, соответствует ли x
"0
.
Оба этих термина определяются спецификацией Javascript.
Ответ 3
Вот интересный вопрос относительно непустой строки, которая имеет только пробельные символы:
!!" "; // true
" " == true; // false
Это происходит потому, что когда вы выполняете сравнение ==
, а одно из сравниваемых значений - это число или логическое значение, делается попытка преобразовать другое значение в число.
Причина, по которой вы получаете другой результат, состоит в том, что строка с символами пробела преобразуется в число 0
(или falsey), а строка с пробелами, преобразованная только в boolean через !!
, рассматривается как непустая строка и, следовательно, true
.
Итак:
var x = " ";
alert( !x ); // false
alert( x == 0 ); // true
EDIT:
Вероятно, важно помнить, что при сравнении числа или булевых значений с типом non number ==
, если возможно, использует преобразование toNumber, тогда как !
использует toBoolean-преобразование. Они не всегда одинаковы.
Легко увидеть результат преобразования toBoolean, используя !!
. Как в:
alert( !![] ); // true
Но вы не можете увидеть результат преобразования toNumber при использовании ==
.
Однако вы можете использовать унарный +
, чтобы увидеть результат преобразования toNumber. Как в:
alert( +[] ); // 0
Я уверен, что то, что происходит в случае массива, заключается в том, что он сначала получает вызов toString
. Поэтому:
// ---------------------toString result-------toNumber result (from string)
alert( +[] ); // "" 0
alert( +[""] ); // "" 0
alert( +[" "] ); // " " 0
alert( +[0] ); // "0" 0
alert( +["0"] ); // "0" 0
alert( +["3"] ); // "3" 3
alert( +[3,4] ); // "3,4" NaN
Ответ 4
Короткий ответ: они почти всегда одинаковы, но не на 100% одинаковы.
Примером может быть (!'0')
, который является ложным, тогда как ('0' == 0)
является истинным
Детали:
От: http://www.joeyjavas.com/2007/08/04/javascript-true-false-checking-for-boolean-values/
Проверка правильности значения true или false в JavaScript. Все значения оцениваются как true, кроме:
0
-0
null
undefined
NaN
empty string
false
Следовательно, (!x)
будет истинным для всех вышеперечисленных значений x
и только тех.
Что касается (x == 0), это будет верно для любого значения x, которое - при преобразовании в соответствии с правилами преобразования "==" - преобразуется в 0 по сравнению с числом (например, Boolean false
value). Другими примерами, сравнивающими true с ==0
, являются объекты, которые генерируют 0 из своих методов valueOf()
или строку '0'
, или пустой массив ([]
)
Ответ 5
Разница между ними заключается в том, что
if ( x ) { ... }
Проверяет, является ли x "правдивым"
В то время как
if ( x == 0 ) { ... }
Производится ли принуждение типа между x и 0.
Я предполагаю, что вы имеете в виду что-то вроде
if (x == 0) vs if (!x)
Основное отличие - это принуждение типа x к числу против проверки, если x является ложным.
Ясно, что NaN
сам никогда не будет равен 0, так как его не число. undefined
также будет принуждать к NaN, так что не поймается == 0
Я не могу дать хорошее объяснение, почему null
не поймано 0
, так как Number(null) == 0
Ответ 6
Первый тест будет успешным, если x
отличен от нуля или оценивается объектом (в отличие от null
или undefined
) или является непустой строкой. Поэтому, если x
равно 0, условие не работает, но если оно равно "0" , то оно преуспевает.
Второй тест будет успешным, если x
конвертируется в 0. Это означает, что он не должен быть null, undefined или объектом для прохождения этого теста. И это может быть "0" или "".
Другими словами, эти условные обозначения не являются противоположностями. Например, значение "0" будет проходить оба теста.
Ответ 7
Фрагмент кода 1 будет выполняться, если x
является "ложным" значением. В Javascript это означает 0, -0, null, undefined, NaN, "или false. Code Snippet 2, однако, будет выполняться только в том случае, если x
равно нулю. В отличие от первого условия, это не включает другие" ложные" значения.
Ответ 8
После некоторых поисков, измените мой тент.
Нет простой логики, неявные операции равенства следует алгоритму.
http://interglacial.com/javascript_spec/a-11.html#a-11.9.3
Я не могу лучше подвести итог тому, что описывает алгоритм, он просто станет более запутанным.
Итак, это (!x)
эквивалентно (typeof x === false)
aka (не верно)
И (x == 0)
сравнивается по алгоритму.