2016-01-30 3 views
1

Мы предполагаем, что у нас есть 3 переменные: а, б и вСравнение Поведение JavaScript объектов

var a = new Boolean(true); 
var b = true; 
var c = new Boolean(true); 

console.log("First comparison : ", a == b); 
// true 
console.log("Second comparison : ", b == c); 
// true 
console.log("Contradiction : ", a == c); 
// false 

Я уже знаю, что ключевое слово «новый» создает новый объект. Тип этого объекта - просто объект.

Математически, как мы можем объяснить это противоречие?

+3

Два разных объекта никогда не будут сравниваться как равные. – Pointy

+3

a == c Вы сравниваете ссылки на два объекта вместо ссылки на объект с примитивными данными –

+1

Возможный дубликат [http://stackoverflow.com/questions/35104913/behaviour-of-javascript-objects](http://stackoverflow .com/questions/11704971/why-are-two-same-objects-not-equal-to-each-other) –

ответ

3

В первых двух примерах, поскольку сравнение включает в себя примитивное значение b, a и c в конечном итоге принуждаются к примитивам. В последнем случае, с другой стороны, вы сравниваете два разных объекта, и поэтому никакого принуждения не происходит.

Чтобы быть точным, дважды равным сравнение с булевым использует это правило из спецификации (принимая случай b == c):

Если Type(x) является Boolean, возвращает результат сравнения ToNumber(x) == y.

Значит, это означает, что ToNumber(b) сравнивается с c. ToNumber(b) - 1. Таким образом, мы сравниваем 1 с c. Далее, следующее правило:

Если Type(x) либо String или Number и Type(y) является Object, возвращает результат сравнения x == ToPrimitive(y).

Таким образом, это означает, что мы сравниваем 1 с ToPrimitive(c) которая ToPrimitive(Boolean(true)). ToPrimitive вызывает valueOf, что дает 1. Поэтому мы сравниваем 1 с 1. QED.

В случае Вашего третьего примера, следующая часть спецификации применяется:

Если Type(x) такая же, как Type(y), то ... Возвращает истину, если x и y относятся к одному объекту. В противном случае верните false.

Чтобы ответить на ваш вопрос:

Математически, как мы можем объяснить это противоречие?

Это не вопрос математики. Это вопрос определения сравнений в спецификации JS.

+0

Если вы хотите получить дополнительную информацию о принуждении, ознакомьтесь с https://github.com/getify/You- Dont-Know-JS/blob/master/types% 20 &% 20grammar/ch4.md – gpersell

0

Эта проблема заключается в том, как Javascript сравнивает значения объектов и букв.

Эта статья посвящена «равенства объектов» в JavaScript: http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html

В целом, для объектов Javascript только сравнивает ссылки (если две переменные относятся к одному объекту).

0

Математически, как мы можем объяснить это противоречие?

Если вы думаете, что это противоречие, вероятно, потому, что вы предположили, что == определяет equivalence relation.

Но это не так:

  • Это не удовлетворяет reflexivity, например, NaN != NaN.
  • Это не удовлетворяет transitivity, как вы заметили.
  • Он удовлетворяет symmetry, хотя этого недостаточно.
0

Я не думаю, что такое поведение можно объяснить с математической точки зрения.

Что вы делаете для переменных a и c, обычно называете «бокс»: принимая примитивное значение Javascript (undefined, null, String, Number, Boolean, Symbol в ES6) и вызывая его с помощью оператора new.

Результат:

var a = new Boolean(true);

является Javascript Object обертывания Boolean элементарного значения.

Та же картина вызов неявно происходит, когда вы используете примитивное значение в зависимости от контекста (this) в некоторых языке встроенные средства, такие как Function.prototype.call и Function.prototype.apply

Даже заменяющего == с === даст те же результаты , и это связано с тем, как сравнение объектов в JS.

+0

Я не думаю, что вы можете поле null и undefined. Кроме того, замена '==' на '===' не принесет одинаковых результатов для первых двух сравнений. –

+0

«Принимая примитивное значение Javascript (undefined, null, String, Number, Boolean, Symbol в ES6) и вызывая его с помощью нового оператора» --- это неверно. 'Boolean' не является примитивным значением, это конструктор. – zerkms