-4

If debugging shows that a variable is 0, then I think that I should be able to catch it with either ==='0' or ===0 but that didn't work. I had to use only == instead, then it worked:

var offset = 0;
alert("## DEBUG non_sortable_columns " + non_sortable_columns)
if (non_sortable_columns == '0' || non_sortable_columns == 0) {
    offset = 1;
}

I first tried this but it didn't work:

var offset = 0;
alert("## DEBUG non_sortable_columns " + non_sortable_columns)
if (non_sortable_columns === '0' || non_sortable_columns === 0) {
    offset = 1;
}

The value was [0] and [0] === [0] is false. How can it be false?

Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424

3 Answers3

1

I just did the following test

var num = 0;

console.log("Number: ", num);

if(num === '0' || num === 0) {
    console.log("Num is 0 (===)");
}

if(num == '0' || num == 0) {
    console.log("Num is 0 (==)");
}

and got the output

Number:  0
Num is 0 (===)
Num is 0 (==)

Try console.log the value itself, if you alert or append strings to a number in JS it will always output as a string. This can be misleading when trying to debug code.

Sean
  • 1,444
  • 1
  • 11
  • 21
  • The value seemed to have been `[0]` which I couldn't test for so I changed it to `0` at the backend and tested for that instead. Then it worked. – Niklas Rosencrantz Nov 17 '17 at 17:20
1

The value of non_sortable_columns might be false. The basic difference between the === and == is that the 3 equals to comparison operator also checks the type of the variable, that means: '0' which is a string would not be equal to: 0 which is a number.

In your case the variable non_sortable_columns value might be false which means 0in JavaScript therefore the value of the == finds it same as it doesn't check the type but === fails as it checks the type of it.

For better understanding refer to: Which equals operator (== vs ===) should be used in JavaScript comparisons?

Karan Dhir
  • 731
  • 1
  • 6
  • 24
1

1. [0] === [0] is false because each [0] is actually a declaration that creates an array with the number 0 as its first index.

Arrays are objects and in JavaScript, 2 objects are == or === only and only if they point at the same location in memory. This means:

var a = [];
var b = a; 
console.log(a == b); // "true". They both point at the same location in memory. 

a = [];
b = [];
console.log(a == b); // "false". They don't point at the same location in memory.



2. [0] == "0" evaluates to true, because:

In JavaScript, due to the nature of the == operator, when you compare an object with a primitive, the object will be coerced to a primitive, and then that primitive will be coerced to the specific type of primitive you are trying to compare it with.

"0" is a string, so [0] will have to be coerced to a string. How ? First, JavaScript will invoke its valueOf method to see if it returns a primitive, the array version of valueOf will just return that array, so valueOf doesn't yield a primitive; now JavaScript will try the object's (aka array's) toString method, an array's toString method will return a string that is the result of a comma-separated concatenation of its elements (each element will be coerced to a string as well, but that is irrelevant here), this would have been more visible if your array contained more than one element (e.g if it were [0,1], toString would return "0,1"), but your array only has 1 element, so the result of its stringification is "0" (if toString didn't return a string but another primitive, that primitive would be used in a ToString abstract operation; if neither valueOf nor toString returned a primitive, a TypeError would be thrown).

Now, our end comparison, with all the coercions and stuff, has changed to "0" == "0", which is true.


3. [0] == 0, mostly the same as #2, except after JavaScript has the string "0", it will coerce it to a number, the result of coercing the string "0" to a number is the number 0. So we have 0 == 0 which is true.


4. [0] === 0 and [0] === "0", these 2 are very simple, no coercions will happen because you are using ===. In the first one, the reference (aka location pointed at in memory) held by [0] will be compared to the number 0, this will obviously evaluate to false; In the second one, again, the reference held by [0] will be compared with the string "0", this again, is false.


So, as you can see, good ser, all your misery comes from ==, this operator, along with !=, are called "the evil counterparts of === and !==" by Douglas Crockford, for the same reasons which are causing your confusions.

Feel free to request any elaborations you might want and ask any questions you might have.

Additionally, see this article about object coercion, this MDN article about Array#toString, and this StackOverflow question which outlines the differences between == and ===.

doubleOrt
  • 2,407
  • 1
  • 14
  • 34