Литье по типу JavaScript

Рассмотрим пустой массив JavaScript:

var a = [];
alert(a == false); // shows true
alert(!a); // shows false!

Как это объяснить? Каковы правила?

Ответ 1

Из http://forums.whirlpool.net.au/archive/966449:

a == false:

В этом случае тип левой стороны - это объект, тип правой части - логический. Javascript сначала преобразует логическое значение в число, получая 0. Затем он преобразует объект в "примитив", давая пустую строку. Затем он сравнивает пустую строку с 0. Пустая строка преобразуется в число, получая 0, который численно равен 0 в правой части, поэтому результат всего выражения true.

См. §11.9.3 спецификацию ECMAScript для всех подробностей gory.

(!a):

В этом случае Javascript преобразует объект в логическое значение true, а затем инвертирует его, что приводит к ошибке.

Ответ 2

Оператор ! проверяет, является ли его операнд "ложным".

Верно следующее:

  • !false
  • !0
  • !null
  • !NaN
  • !undefined
  • !""

Оператор == проверяет свободное равенство, которое не имеет ничего общего с ложностью.

В частности, a == b преобразует в операнды числа, а затем сравнивает числа.
Строки, содержащие числа, преобразуются в числа, которые они содержат; booleans преобразуются в 0 и 1.
Объекты преобразуются путем вызова valueOf, если они определены.

Таким образом, все следующее верно:

  • "1" == 1
  • "0" == false
  • "1" == true
  • "2" != true
  • "2" != false
  • ({ valueOf:function() { return 2; } }) == 2
  • ({ valueOf:function() { return 1; } }) == true

Ответ 3

Оператор ==, когда один из операндов, если имеет значение Boolean, преобразовывает другое в число.

[] == 0;

Является эквивалентным:

0 == 0;

Вы можете увидеть полную информацию о Алгоритм сравнения абстрактного равенства в спецификации.

Как вы можете видеть, пустой объект массива при преобразовании в число производит 0:

+[]; // 0
Number(0);

Это действительно потому, что его метод toString создает пустую строку, например:

[].toString(); // ""

+""; // 0
Number(""); // 0

Ответ 4

При сравнении объекта с примитивным значением с помощью оператора == объект зацикливается на самом примитивном значении (число или строка). В этом случае [] заходит в 0, тогда false заходит в 0:

[] == false
0 == false
0 == 0

что верно.

Оператор ! замыкается в boolean, а затем инвертирует значение. [] в boolean true (например, с любым объектом). Затем инвертируйте, чтобы стать false

![]
!true
false

Ответ 5

Не уверен, что это отвечает на вопрос, но есть новая библиотека для обхода всех неизвестных Javascript:

Typecast.js

В предложении Typecast решает все простые проблемы, поэтому вы можете сосредоточиться на больших. Typecast исправляет ошибки в Javascript, создавая полную платформу для сильно типизированных переменных в Javascript.