2016-02-09 5 views
0

Я сохраняю (x, y) координаты как 2-элементные массивы.В Javascript, почему [1,2] == [1,2] разрешено false?

var coordinateA = [0,3]; 
var coordinateB = [1,2]; 

Я также имеют более длинный массив, содержащий многие из этих координат:

var coordinates = [coordinateA, coordinateB] 

Представьте себе мое удивление, когда следующие утверждения оказались ложными:

jQuery.inArray(coordinateA, coordinates); // returns -1 
coordinateA == coordinates[0];   // returns false 
[0,3] == [0,3];       // returns false(!) 
coordinateA == coordinateA;    // returns true, thankfully 

Может кто-нибудь мне помочь понять, почему это так? Кроме того, есть ли лучший способ представить 2D-координаты в Javascript? Спасибо за любые подсказки или предложения.

+0

См [этот вопрос] (http://stackoverflow.com/questions/4700085/can-i-define-custom-operator-overloads-in-javascript) для альтернативного –

+6

сравнения двух объектов определяет, если они являются одним и тем же объектом, контент не сравнивается. – Teemu

+0

На самом деле, если вы установите массив координат так, как вы описали, он должен работать так, как вы ожидаете (элемент в координатах [0] 'и' coordAA * shoud * указывает на ту же память). У меня есть чувство, что проблема находится где-то в другом месте или зависит от браузера (только что подтвердил, что он работает так, как ожидалось, в хроме) – JCOC611

ответ

4

Это потому, что у вас есть два отдельных массива ссылки.

Оператор равенства проверяет, что ссылки равны, а не содержимое массивов.

+1

Это также относится к пустым массивам. На всякий случай кто-то задается вопросом. – Vasif

-1

Одна из загадочных вещей, связанных с JavaScript, заключается в том, как разрешается равенство. Я сделаю все возможное, чтобы объяснить это.

Правила равенства могут быть довольно трудно понять. Вообще говоря, вы можете сравнить относительное равенство (==) или строгое равенство (===).

относительное равенство:

Это сопоставимо только значение и не заботится о типе.

Пример

var x = '2'; 
var y = 2; 
x == y; 
=> false; 

В относительном равенстве, строка "2" равно числу 2. Это будет возвращать верно, так как типы не сравнивается

строгого равенства

Это сопоставимы оба значения и тип.

Пример

var x = '2'; 
var y = 2; 
x === y; 
=> false 

В этом случае строка "2" не равен номер 2. Поскольку строки и номер два различных типа.

Сравнение с массивами и объектами выполняется по-другому.

В вашем случае массивы считаются объектами.

typeof([1,2]) 
=> "object" 

В JavaScript все объекты разные. Их сравнивают с идентификаторами объектов. Чтобы определить, равны ли массивы, вы должны выполнить type conversion в строке.

String([1,2]) == String([1,2]) 
=> true 

Однако underscore библиотека имеет is_equal метод, который может определить, является ли два массива равны

_.isEqual(array1, array2); 

Подчеркивание делает это путем выполнения deep comparison между двумя объектами, чтобы определить, должны ли они быть считаются равными.

Важно отметить, что порядок здесь имеет значение, как и в сравнении строк.

_isEqual([1,2], [1,2]) 
=> true 

_isEqual([1,2], [2,1]) 
=> false 
+3

* «относительное равенство - сравнивается только по значению и не заботится о типе». * Это просто неправда. И '==' и '===' очень заботятся о типе, а на самом деле '==' больше заботится. Когда типы совпадают, '==' и '===' идентичны, но когда они не совпадают, '==' делает дополнительный анализ типов, чтобы увидеть, могут ли операнды быть преобразованы в соответствующие типы и рекурсивно вводит алгоритм до тех пор, пока не будут найдены совпадающие типы и сравниваемые значения. –

+0

* «Чтобы определить, равны ли массивы, вам необходимо выполнить преобразование типов в строку». * Вам не обязательно, и на самом деле это ненадежный способ сравнения: 'String ([1,2]) == Строка ([ "1,2"]); // true' –

Смежные вопросы