2013-11-13 4 views
2

Я изучаю JavaScript уже некоторое время, и я знаю лучше, чем на самом деле полагаться на такое поведение, но мне становится любопытно ... почему пустой массив [] казалось бы, противоречивые логические тождества?JavaScript: weird boolean values ​​for []

Это truthy: [] && true вычисляет true ... и тем не менее, это неверно: [] == false вычисляется в true.

Однако его двойное отрицание верно: !![] оценивает по: true. Но это также (используя свободное равенство), равное его собственному отрицанию: ![] == [] оценивает true.

Его числовое значение является фальшивым: +[] && true оценивается в 0.

Его строковое представление является фальшивым: [].toString() && true оценивает по: "".

Есть ли ясная причина, почему [] является такой загадкой?

ответ

1

Я думаю, что результаты являются разумными. Единственный, на котором я нахожусь, - +[], но я мог бы это понять. Это похоже на то, что вы сказали, что свободное сравнение может ввести в заблуждение, но это имеет смысл для меня.

console.log([] && true); //true - there is an array 

console.log([] == false); //true, the array is empty 

console.log(![]); //false, there is an array 

console.log(!![]); //true, there isn't not an array 

console.log(![] == []); //true, no array is loosely like an empty array 

console.log(+[]); //0, I think this converts the array to a number, 0 being the logical choice. +[1] will return "1" and +[1,2] is "NaN" - which seems to be because the conversion is no longer feasible. 

console.log([].toString()); //string '', as expected - also see next example 

console.log(['stuff',{}].toString()); //stuff,[object Object] 
+0

Но это не объяснение, почему это так. Например, первая из них истинна, потому что каждый объект имеет значение true (логическое преобразование). И второе: да, оно пустое, но что там происходит. Я думаю, что false преобразуется в 0. –

+0

Он специально не спрашивал, как работает интерпретатор, он просто спросил, почему '[]' оценивает странно. Я предлагаю, чтобы это была не «головоломка», и результаты были разумными. – m59

0

Я не могу дать вам полный ответ, но вот некоторые наблюдения:

Как вы знаете, что есть Boolean функция, которая возвращает логическое значение и принимает параметр, таким образом, он очень напоминает отливку обмануть. Boolean([]) возвращает true, что объясняет, почему [] && true is true, ![] is false и !![] - это правда.

С другой стороны, конструктор Number([]) возвращает 0, что объясняет, почему +[] && true равно нулю.

Другое дело, что String([]) пустая строка, String(true) является строка "true" и "" && "true" является "", который прекрасно вписывается в мой великой схеме, как вы увидите ниже.

Теперь о любопытных вещах. Вот что я выяснил:

Number(![]) is 0, Number([]) равно 0. В этом случае Number(![]) == Number([]), очевидно, верно.

Number([]) является 0, Number(false) является 0, таким образом Number([]) == Number(false).

Мне кажется, что всякий раз, когда JS не может напрямую сравнивать два объекта (ни один из которых не является строками), он отбрасывает их на числа, а затем сравнивает. Если одна из них является строкой, она всегда преобразуется в строку и затем оценивает любые функции. По крайней мере, это объяснило бы странное поведение, которое вы заметили.

0

& & Возвращает expr1, если оно может быть превращено в ложь; в противном случае возвращает expr2.Таким образом, при использовании с булевыми значениями & & возвращает true, если оба операнда могут быть преобразованы в true; в противном случае возвращает false.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

В вашем случае

+[] // 0 - is falsy so it will be returned 
[].toString() // "" - is falsy so it will be returned