! оператор в JavaScript
Я сейчас смущен! оператор в JavaScript. Мое понимание было! оператор работает только с булевым. Но комментарий к одному из моих ответов говорит, что он может работать на что угодно и возвращает логическое значение, которое оказалось истинным после нескольких тестов.
alert(!undefined); //true
alert(!function(){}); //false
alert(!{}); //false
alert(!null); //true
alert(!()); //crash
alert(!"false"); //false
alert(!false); //true
Может кто-нибудь помочь мне обобщить поведение! Оператор.
ИЗМЕНИТЬ
Еще более запутанный материал:
alert( new String() == ""); //true
alert(!""); //true
alert(! new String()); //false
Как?
Ответы
Ответ 1
!
делает то, что вы думаете: обращается к false и наоборот. Странное поведение связано с тем, как Javascript может преобразовать буквально все в true
или false
.
http://11heavens.com/falsy-and-truthy-in-javascript
Как и в C (только хуже), все значения могут быть переведены в true или false. Необходимые условия поиска - "правдивые" и "ложные", "правдивость" и "ложность". Truthy означает, что что-то преобразуется в true, ложь означает, что что-то превращается в false. Все значения являются правдивыми, кроме null
, undefined
, 0
, ""
, NaN
и... false
В этой ссылке есть более интересные примеры:
http://www.sitepoint.com/javascript-truthy-falsy/
И этот сайт действительно любит делать патологические вещи с забавным поведением здесь:
http://wtfjs.com
Также обратите внимание, что ==
действительно пытается сделать вещи сопоставимыми, тогда как ===
просто возвращает false
, если вещи не сопоставимы. Crockford в Javascript: The Good Parts рекомендует не использовать ==
полностью.
Ответ 2
Это не столько функция !
как функция того, что есть или не является true
в javascript. Если вы знакомы с кастингом, то принуждение переменной к определенному типу, то следующее должно быть достаточно понятно для вас.
!
работает только с булевыми. Поэтому любая переменная, которую вы применяете к ней, не является логической, сначала принудительно вводится в значение boolean перед применением !
. Чтобы связать это с вашими примерами:
Boolean(undefined) == false
undefined является своего рода нулевым значением в javascript (есть некоторые отличия, но это другая тема). Следует иметь в виду, что булевым эквивалентом является false
. undefined
выходит за пределы просто отсутствия значения, он объявляет, что переменная, которую вы пытаетесь использовать, даже не существует.
Boolean(function(){}) == true
Функции - это объекты в javascript. Даже если он пуст, он все еще имеет некоторые базовые свойства, общие для объектов функций, и поэтому его булевский эквивалент true
. Это не ничего, и это что-то.
Boolean({}) == true
Как и пустая функция, {}
определяет пустой объект. Тем не менее, он все еще имеет некоторые свойства, общие для объектов в javascript. Он просто не имеет настраиваемых свойств.
Boolean(null) == false
Как я уже упоминал для undefined
, null
аналогичен, но не совсем то же самое. Это указывает на отсутствие значения.
Boolean(()) // error
()
сами по себе ничего не значит. Вам нужно что-то между ними, чтобы сделать синтаксис правильным, чтобы это не повлияло на ваш ложный/истинный вопрос. ()
- просто синтаксическая ошибка.
Boolean("false") == true
"false"
- строка. Просто потому, что он содержит буквы f, a, l, s, e, не делает их такими же, как булево значение false
. Непустая строка - это что-то и поэтому приводит к булевому true
. Строки примечаний являются особыми объектами, в которых пустая строка ""
приводит к false
, но пустой объект {}
, как уже упоминалось, принуждает к true
.
Boolean (false) == false
Это должно быть ясно. false
уже является булевым, поэтому его литье не изменяет его значение. Он еще false
.
Из этого вы можете видеть, как применение !
к каждому случаю даст вам результаты, которые вы видели.
Для дальнейшего чтения здесь довольно хорошая статья о типе принуждения в javascript
UPDATE:
В отношении ваших вопросов String
. Существует другой объект String
и строковый литерал (что-то окруженное кавычками). Вы можете создать объект String
из строкового литерала, но литерал не является автоматически объектом. То же самое относится к номерам в javascript. JS имеет объект Number
, но вы часто определяете числовые литералы. Поведение Number
соответствует тому, что вы видели с помощью String
:
alert( new Number() == 0); //true
alert(!0); //true
alert(! new Number()); //false
Однако, как вы точно упомянули в своем комментарии:
alert( new String() === ""); //false
Поскольку типы не совпадают; объект против литерала.
В общем случае Boolean(some_object)
всегда будет оцениваться как true
, но в зависимости от точного значения Boolean(some_literal)
может оцениваться как false.
ДОПОЛНЕНИЕ
Просто потому, что я выстрелил себе в ногу раньше на этой неделе, я думал, что это будет полезная информация для добавления. В большинстве языков пустой массив, []
, будет принужден к false
. Однако в Javascript массивы являются объектами, поэтому даже пустой массив приближается к true
. Один, на что нужно следить. При переключении между js и различными языками на стороне сервера легко сделать проскальзывание вдоль линий if(!maybe_empty_array){...}
, которые никогда не пройдут, потому что maybe_empty_array
всегда будет принуждать к true
. Вместо этого вы должны сделать if(maybe_empty_array.length){...}
. Если массив пуст, его длина равна 0, что безопасно приближается к false
.
Ответ 3
"Может кто-нибудь помочь мне обобщить поведение оператора!"
Конечно. Он возвращает false, если его единственный операнд может быть преобразован в true; в противном случае возвращает true.
Любой объект (включая "пустой" объект, {}
или функцию), любую непустую строку и любое ненулевое число могут быть преобразованы в true. С другой стороны, null, undefined, пустая строка и нуль будут преобразованы в false. Затем оператор !
возвращает обратное, следовательно, результаты, которые вы показываете в своем вопросе.
Ответ 4
! возвращает false, если его единственный операнд может быть преобразован в true или если это небулево значение:
!(x == y)
!"something"
И true, если его операнд можно преобразовать в false:
!(x > y)
Ответ 5
Будет сложно написать более обобщенное объяснение, чем это:
var arr = [0, "", false, null, undefined, NaN];
for(var i = 0; i < 6; i++){
console.log(!(arr[i]));//always true
}
Любые другие значения будут выдавать false