2

I was asked to write a function sortByFoo in Javascript that would react correctly to this test :

// Does not crash on an empty array
console.log(sortByFoo([]) === []);

But I've tried something :

[] === [];
>> false

Just so I can be sure, such a test would always fail, no matter the sortByFoo function, wouldn't it ? But I'd like to have an explanation on why this happens. Why [] isn't identical/equal to [] ?

Please forgive my approximate english, it is not my native language :p

Zong
  • 6,160
  • 5
  • 32
  • 46
Mat
  • 952
  • 2
  • 11
  • 28

4 Answers4

4

If you look at the specification for javascript/ecmascript, particularly section 11.9.6, you will see how comparisons with === are performed.

The Strict Equality Comparison Algorithm

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 different from Type(y), return false.
  2. If Type(x) is Undefined, return true.
  3. If Type(x) is Null, return true.
  4. If Type(x) is Number, then
    • If x is NaN, return false.
    • If y is NaN, return false.
    • If x is the same Number value as y, return true.
    • If x is +0 and y is −0, return true.
    • If x is −0 and y is +0, return true.
    • Return false.
  5. 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.
  6. If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
  7. Return true if x and y refer to the same object. Otherwise, return false.

Since your arrays go all the way down to the seventh step they will have to be the same object, not just two identical objects. The same goes for the regular equality operator (==).

Karl-Johan Sjögren
  • 16,544
  • 7
  • 59
  • 68
  • [off topc] Why did you approve [the edit mentioned here](http://meta.stackexchange.com/q/211655/180276)? It should have been rejected – tckmn Dec 15 '13 at 16:08
  • I had a quick read of the edit and it looked reasonable enough though as `rene` mentioned on Meta I don't have a lot of experience on those particular tags. – Karl-Johan Sjögren Dec 15 '13 at 16:21
  • 1
    Okay, then please just be more careful while reviewing. (And use Skip when you're not sure and you don't have much experience.) Thanks! – tckmn Dec 15 '13 at 16:24
3

Because every time you write [] you are calling array's constructor.

[] is the same as new Array(), and in Javascript new objects compared with equals method are different. See the reference, it is the same as new Object() when using {}.

pdjota
  • 3,163
  • 2
  • 23
  • 33
2

When you do [] === [] you're comparing references and not values (or deep comparison by values).

Take a look at this solution for javascript array comparison: Comparing two arrays in Javascript

Community
  • 1
  • 1
Italo Borssatto
  • 15,044
  • 7
  • 62
  • 88
1

Yes, you are correct that two array literals are never equal. That's because they are references to two separate instances of arrays.

The code to describe the test should be written:

var arr = [];
var result = sortByFoo(arr);
console.log(result === arr && result.length == 0);

Checking that the reference returned by the function is the same that was sent in, and that the array is still empty, ensures that the function returned the same array unchanged.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • That only works if `sortByFoo` returns the array it is provided with. – Stilltorik Dec 09 '13 at 15:23
  • @Stilltorik: Yes, and there is no reason for the function to return a new array instead. – Guffa Dec 09 '13 at 15:27
  • It really depends on the specs. If it modifies the provided array directly, you're loosing the original order. It may or may not be acceptable. – Stilltorik Dec 09 '13 at 15:52
  • @Stilltorik: Even if the sorted array should be returned as a new array, there is still no reason to create a new array when it's unchanged. – Guffa Dec 09 '13 at 18:04
  • @Guffa client code may depend on the fact that `.sort` does not work in-place and normally returns a new array... I would say that there is no reason to create a special case when creating an array is so cheap. – Jacob Raihle Jul 03 '15 at 16:30