Omar_0x80
Omar_0x80

Reputation: 813

Comparison Behaviour of JavaScript Objects

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 ?

Upvotes: 1

Views: 71

Answers (3)

user663031
user663031

Reputation:

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.

Upvotes: 3

Francesco Pezzella
Francesco Pezzella

Reputation: 1795

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.

Upvotes: 0

Oriol
Oriol

Reputation: 288520

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.

Upvotes: 0

Related Questions