1 presumably not equal to 1

103 Views Asked by At

I got a surprise today and I couldn't find the appropriate part of the specification to find out whether this was to be expected or not. My money is on that there's nothing wrong with the universe but what are the rules that make this expression evaluate to false

(function(){ return this;}).call(1) === 1
5

There are 5 best solutions below

5
On BEST ANSWER

what are the rules that make this expression evaluate to false

In "loose" mode the value of this is always coerced to an object. Values of type Object are not (strict) equal to values of type Number (or any other type for that matter):

new Number(1) === 1 // false

From the spec:

Entering Function Code

  1. If the function code is strict code, set the ThisBinding to thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.
  3. Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg).
    ...
1
On

depending of 'strict mode';

in strict mode: true (type is number)
without strict mode: false (type is object)
1
On

Try checking the result of that function:

(function(){ return this;}).call(1)

You can see that the result is Number {[[PrimitiveValue]]: 1} so the result is an object not a primitive type. Since you are using three equals you are requesting that the type is the same:

(function(){ return this;}).call(1) === 1 // => FALSE

(function(){ return this;}).call(1) == 1  // => TRUE

This is not the strangest thing about javascript belive me ;-)

2
On

The primitive 1 is converted to an Number object when it is set to this in .call because this is in javascript always an object.

And [Number: 1] is not strictly (===) the same as the primitive 1.

But when using the non-strict equality operator (==) the Number object is converted to a primitive for comparison.

0
On

(function(){ return this;}).call(1) returns an Object of type Number, according to FF developper console:

enter image description here

Whilst 1 is of a primitive type.