3

Can someone please describe the outcome of these expressions?

  [1, 2, 4] < [1, 2, 5]  // true
  [1, 3, 4] < [1, 2, 5]  // false


  [1, 2, 3] === [1, 2, 3]   // false
  [1, 2, 3] <   [1, 2, 3]   // false
  [1, 2, 3] ==  [1, 2, 3]   // false
  [1, 2, 3] >   [1, 2, 3]   // false


  [1, 2, 3] <= [1, 2, 3]   // true
  [1, 2, 3] >= [1, 2, 3]   // true

Thanks for help and fast answer !

10
  • 9
    Two arrays will never be == or ===, as long as they refer to different arrays (even if they look the same or have the same contents). The comparison for arrays (which are objects) is by reference, and two new arrays aren't the same reference at all. As for the < and > - I'm pretty sure the arrays are converted to string (like [1, 2, 3] is converted to 1,2,3) and compared (like alphabetically) Commented May 15, 2013 at 13:47
  • @Ian but still somehow this is not logical or is it ? .. and what is with that example new Array([],null,undefined,null) == ",,,"; // true Commented May 15, 2013 at 13:50
  • Sure it's logical...especially for == and ===. As for < and > - what would you expect to happen? Commented May 15, 2013 at 13:52
  • 1
    How many question regarding the quirks of JS comparison operators does SO need? Commented May 15, 2013 at 13:52
  • 1
    I didn't downvote, and don't agree with whoever downvoted. It's not a bad question. But I voted to close because there are many other similar questions, so this can be considered a duplicate. This is not as bad as you think, you already got 5 answers, you accepted one, and the duplicate link at the top (as well as the other links on the right column) can be helpful to future visitors. The question will stay around, containing valuable answers and links to related content. Commented May 15, 2013 at 14:16

4 Answers 4

4

Equality =

[1, 2, 3] == [1, 2, 3]

is described under The Abstract Equality Comparison Algorithm, which basically says

(if x or y are primitives, compare them, otherwise...)
Return true if x and y refer to the same object. Otherwise, return false.

Since different object literals always represent different objects, even if the content is the same, the above comparison fails.

Relational operators < >

Relative comparisons are different from equality. When you use < or >, arrays are compared as strings.

[1, 2, 4] < [1, 2, 5] 

The Abstract Relational Comparison Algorithm converts both operands to primitives. If an operand is an object, ToPrimitive calls [[DefaultValue]] which in turn is the same as obj.valueOf().toString(). Since valueOf of an object is the object itself, the whole thing boils down to

"1,2,4" < "1,2,5"

A common assumption that arrays are compared element-wise is not true:

[10,1,3] < [101,5]  // false

Note that valueOf can be overridden to affect the behavior of relational operators:

> a = [1,2,3]
[1, 2, 3]
> a < [1,2,4]
true
> a.valueOf = function() { return 'zzz' }
function () { return 'zzz' }
> a < [1,2,4]
false
Sign up to request clarification or add additional context in comments.

Comments

3

In JavaScript almost everything is an Object. There are primitive types which auto-box between primitive and Object version as needed.

When you compare Objects in JavaScript, you are actually comparing if they are the same reference(e.g point to the same memory address). Proof here

 var a = [1, 2, 3];
 b = a;
 b.push(5);
 console.log(a); // 1, 2, 3, 5

In this case a == b or a === b will yield true. If I want to compare two separate arrays, then I need to loop through them and compare element by element.

In the following case, I can use a trick though. Live demo

var x = [1, 2, 3];
var y = [1, 2, 4];
var z = [1, 2, 3];
var equals = x.join("").localeCompare(y.join("")) == 0; //x with y
var equals2 = x.join("").localeCompare(z.join("")) == 0; //x with z
document.body.innerHTML += equals + "<br />";
document.body.innerHTML += equals2 + "<br />";

In your weird case

Array([],null,undefined,null) == ",,,";

In JavaScript the == operator will perform all the type casts/conversions it can perform to check for equality. It will try to compare a String with String, at which point the left hand side, the Array will be converted to a String using a simple toString() call!

Look here, I guess the answer is now obvious.

5 Comments

I understand you answer and thanks allot for that but how would you explain that .. Array([],null,undefined,null) == ",,,"; // true more or less the same .. or not ?
In Array([],null,undefined,null) == ",,,"; you are comparing against string so it will be like doing Array([],null,undefined,null).join() == ",,,";
so why it the answer true ?
.join() is not used to compare arrays - .toString() is. Not that it matters, since they end up with the same result, and .toString() internally calls .join(), but still
my friend that send me this strange array send now the solution on this page over here wtfjs.com/page/5
1
[1, 2, 3] === [1, 2, 3]   // false
[1, 2, 3] ==  [1, 2, 3]   // false

Arrays are objects in JavaScript and therefore compared by reference (regardless whether with strict or typecasting equality). Two distinct (even if similar) literals always evaluate to distinct objects, which will never equal. To cite the spec,

[If both x and y are of type Object, then] return true if x and y refer to the same object. Otherwise, return false.


[1, 2, 4] < [1, 2, 5]   // true
…

JavaScript's comparison operators do always cast their arguments to primitive values (and then to strings or numbers if needed). On objects, first .valueOf() then .toString() is tried. Arrays will become stringified, and for your simple example "1,2,4" indeed is smaller than "1,2,5". It would not work for complex objects, strings that contain commata or even for [12] vs [2].

2 Comments

When arrays are stringified, the [ and ] characters are not included (not that it matters for a comparison)
@Ian: You're right of course, fixed. Thanks!
0

That's how the equality algorithm has been specified (sec 11.9.3):

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
    • [...]
    • Return true if x and y refer to the same object. Otherwise, return false.

So the following will return true and all other equality comparisons will return false

var x = [1,2,3];
return x == x;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.