16

I am working on a part of the code where I have an array which looks like [[data]]. The data is rendered on the server side through the Django template engine. So my code looks like this:

var data = {{ series|safe }}; 
// data will be [[]] if no data is present
if (data ==[[]])
  console.log('no data');

The if always returns false. That means in [[]] == [[]] is false and my test shows that []==[] is false as well.

Any descriptions would be appreciated.

Hardik Shah
  • 4,042
  • 2
  • 20
  • 41
Nasir
  • 1,982
  • 4
  • 19
  • 35
  • Why the double brackets? – Cerbrus Dec 04 '12 at 12:46
  • 1
    Point 3 at http://coding.smashingmagazine.com/2011/05/30/10-oddities-and-secrets-about-javascript/ contains a description of what you see. – Henrik Aasted Sørensen Dec 04 '12 at 12:46
  • 1
    Related: http://stackoverflow.com/questions/201183/how-do-you-determine-equality-for-two-javascript-objects – Álvaro González Dec 04 '12 at 12:47
  • @Cerbrus it is data series format for jqplot. – Nasir Dec 04 '12 at 12:49
  • `===` is overrated imho, one should not compare different types and even if you do then `===` is always false. Writing `+'5' === 5` is ridiculous when you can just write `'5' == 5` – Esailija Dec 04 '12 at 12:50
  • @Nasir The way to check for this is `data.length === 1 && data[0].length === 0`. Also, @Esailija the example you gave is, in my opinion, the only time it's okay to use `==` (known type number-formatted string against known type number) – Paul S. Dec 04 '12 at 12:59
  • possible duplicate of [JavaScript === vs == : Does it matter which "equal" operator I use?](http://stackoverflow.com/questions/359494/javascript-vs-does-it-matter-which-equal-operator-i-use) – Wooble Dec 04 '12 at 13:49

6 Answers6

17

Because == (and ===) test to see if two objects are the same object and not if they are identical objects.

Most test frameworks will include functions such as deepEqual if you want to see if two objects are identical.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • To see exactly where this happens, see [the Abstract Equality Comparison Algorithm](http://es5.github.com/#x11.9.3) (and note `typeof [] === 'object'`) – Paul S. Dec 04 '12 at 12:49
15

The expression [] == [] has an equivalent notation of:

new Array() == new Array()

And knowing that Array is also an Object, the behaviour of the comparison is unambiguously explained in The Abstract Equality Comparison Algorithm section of the ECMAScript Language Specification:

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

  1. If Type(x) is the same as Type(y), then
    1. If Type(x) is Undefined, return true.
    2. If Type(x) is Null, return true.
    3. If Type(x) is Number, then
      1. If x is NaN, return false.
      2. If y is NaN, return false.
      3. If x is the same Number value as y, return true.
      4. If x is +0 and y is −0, return true.
      5. If x is −0 and y is +0, return true.
      6. Return false.
    4. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
    5. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
    6. Return true if x and y refer to the same object. Otherwise, return false.
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  8. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
  9. If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
  10. Return false.

Your comparison result is explained by 1.6, highlighted above.

Alternative expression

In your case I would suggest to simply use this condition instead:

if (a[0].length == 0) {
    console.log('no data');
}
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
8

Because [] creates a new array, so you are comparing one array object with another array object.

It's not the contents of the arrays that is compared, the object references are compared. They are not equal because it's not the same object instance.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
3

Javascript is like Java in that the == operator compares the values of primitive types, but the references of objects. You're creating two arrays, and the == operator is telling you that they do not point to the same exact object in memory:

var b = new Array( 1, 2, 3 );
var c = new Array( 1, 2, 3 );

console.log(b == c); // Prints false.
console.log(b == b); // Prints true.
console.log(b === c); // Prints false.

b = c;

console.log(b == c); // Now prints true.

You have to do a deep comparison by hand if you want to compare the values of the objects.

Community
  • 1
  • 1
2

Because they are different instances of an Array, thus not equal.

TigOldBitties
  • 1,331
  • 9
  • 15
2

Because Arrays are reference type, meaning, if for example you make an array

let a = [1,2,3,4,5];

let b = a;

the b is actually just a reference of array a, so if you compare them

a===b is true,

because they are basically link together.. So if you change something to array b it will also going to be change to array a,

b[0] = "test";

array a now is ["test",2,3,4,5];

But if you do this this

let a = [1,2,3,4,5];

let b = a.slice(0);

and then compare them

a===b is false

because now they are both different Arrays, meaning if you change the Array b, it will not affect the Array a

b[0] ="hello";

Array a is still [1,2,3,4,5]

while array b is now ["hello",2,3,4,5]

that is also what happen when you compare the []===[] is false

Because basically what you are asking to JavaScript is if they are the same Array which is not

Richard Ramos
  • 61
  • 1
  • 7