1

We suppose that we have 3 variables : a,b and c

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 

I already know that the keyword 'new' creates a new object. The type of this object, is simply object.

Mathematically, how can we explain this contradiction ?

Omar_0x80
  • 783
  • 1
  • 9
  • 16
  • 3
    Two distinct objects will never compare as equal. – Pointy Jan 30 '16 at 17:44
  • 3
    a==c you are comparing two objects references instead of an object reference with a primitive data – Yehia Awad Jan 30 '16 at 17:46
  • 1
    possible duplicate [http://stackoverflow.com/questions/35104913/behaviour-of-javascript-objects](http://stackoverflow.com/questions/11704971/why-are-two-identical-objects-not-equal-to-each-other) – tergd1 Jan 30 '16 at 17:47

3 Answers3

3

In the first two examples, since the comparison involves a primitive value of b, a and c end up being coerced to primitives. In the last case, on the other hand, you are comparing two distinct objects, and therefore no coercion takes place.

To be precise, the double-equal comparison with a boolean uses this rule from the spec (taking the case of b == c):

If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

So this means that ToNumber(b) is compared with c. ToNumber(b) is 1. So we are comparing 1 with c. Next, the following rule is applied:

If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).

So this means we compare 1 with ToPrimitive(c) which is ToPrimitive(Boolean(true)). ToPrimitive invokes valueOf, which yields 1. So we compare 1 to 1. QED.

In the case of your third example, the following portion of the spec applies:

If Type(x) is the same as Type(y), then...Return true if x and y refer to the same object. Otherwise, return false.

To answer your question:

Mathematically, how can we explain this contradiction ?

It's not a matter of mathematics. It's a matter of the definition of comparisons in the JS spec.

  • If you want more information about coercion, check out https://github.com/getify/You-Dont-Know-JS/blob/master/types%20&%20grammar/ch4.md – gpersell Jan 30 '16 at 17:54
0

Mathematically, how can we explain this contradiction?

If you think this is a contradiction is probably because you assumed that == defines an equivalence relation.

But it doesn't:

  • It doesn't satisfy reflexivity, e.g. NaN != NaN.
  • It doesn't satisfy transitivity, as you noticed.
  • It satisfies symmetry, though, but that alone is not enough.
Oriol
  • 274,082
  • 63
  • 437
  • 513
0

I don't think this kind of behaviour can be explained from a mathematical standpoint.

What you are doing on the variables a and c is commonly referred as "boxing": taking a Javascript primitive value (undefined, null, String, Number, Boolean, Symbol in ES6) and calling it with the newoperator.

The result of:

var a = new Boolean(true);

is a Javascript Objectwrapping a Boolean primitive value.

The same invocation pattern implicitly happens when you use a primitive value as the context (this) in some of the language built-in facilities such as Function.prototype.call and Function.prototype.apply

Even replacing ==with === would yield the same results, and that's because of how the Objects comparison work in JS.

Francesco Pezzella
  • 1,755
  • 2
  • 15
  • 18
  • I don't think you can box null and undefined. Also, replacing `==` with `===` would NOT yield the same results for the first two comparisons. –  Jan 30 '16 at 18:03
  • "taking a Javascript primitive value (undefined, null, String, Number, Boolean, Symbol in ES6) and calling it with the newoperator" --- that's not correct. `Boolean` is not a primitive value, it's a constructor. – zerkms Jan 30 '16 at 19:13