18

I know that === is typically referred to as the identity operator. Values being compared must be of the same type and value to be considered equal. Then why below line returns false?

Array("asdf") === Array("asdf")

Om3ga
  • 30,465
  • 43
  • 141
  • 221
  • 2
    As a sidenote, a usual workaround is `JSON.stringify(array1)==JSON.stringify(array2);` – adeneo Dec 07 '12 at 04:59
  • @adeneo Nice, never thought of that. Just as a note for whomever - that wouldn't necessarily work for object literals...which I understand isn't the point of the question, I just wanted to say :) – Ian Dec 07 '12 at 05:02
  • @adeneo Actually, it wouldn't work for arrays that contain objects either. Simple arrays, of course! Again, that's getting more complicated, but still something to think about – Ian Dec 07 '12 at 05:04
  • @Ian - It does not work with all objects, but it does work with 'almost' all arrays, as long as the order is the same in both arrays, as that would'nt just compare values, but that the order is correct aswell. And then there is of course the null != undefined issue, but the chances of running into that one is remote. – adeneo Dec 07 '12 at 05:04
  • 1
    Yeah, I wouldn't use JSON.stringify for comparison because of arrays of objects, functions, etc., and ordering would matter. Not fun. – Eli Dec 07 '12 at 05:06
  • @adeneo So yeah, I was agreeing that it would work with simple arrays - as in, they contain primitive values or arrays with primitive values (of course, assuming the order in the arrays are the same...but I thought that was the point of the question - that the arrays are "identical" but initialized separately). But if you make an array that contains objects that are "identical", there is no guarantee that the objects will be printed the same way with `JSON.stringify`. That was all :) – Ian Dec 07 '12 at 05:08
  • @Eli - It's actually a great way to compare arrays, as long as you know that the arrays contain primitive values and you're also looking to see if the order is the same. – adeneo Dec 07 '12 at 05:08
  • Right, so not useful on all arrays. – Eli Dec 07 '12 at 05:09
  • @Eli - nope, but nothing is really useful on **all** arrays (except maybe Array.isArray) as it all depends on what it contains. – adeneo Dec 07 '12 at 05:10
  • And not even Array.isArray is useful everywhere :D – Eli Dec 07 '12 at 05:12

4 Answers4

39

They are not equal because a new array is being created in each of these statements, each being a brand new array object with just identical contents. If you create two new objects:

var a = {};
var b = {};

a === b // false

When you create new objects, arrays, functions, etc., a brand new object is placed into memory. Creating a new object with the same internals as another object will not magically cause that object to point to one that already exists. The objects may look the same, but they do not point to the same instance. Now if your statement had been like so:

var arr = ['asdf'];

arr === arr; // true

This is obviously be true. === is strict equality, not an identity operator. When objects are ran through a strict equality operator, they are checked to see if they point to the same reference. As I explained earlier, each time you use new Array or [] that a brand new object will be created, each being a new and different reference. So there is no way that two arrays, or any object, can come out === being true unless they point to the exact same array. Just because two objects are being created with identical contents does not mean that they point to the same object, just two identical, but different objects.

Think of constructing functions:

var Car = function (color) {
    this.color = color;
};

var ford = new Car('green');
var chevy = new Car('green');
var toyota = ford;

ford === chevy // false

Just because you are using the same constructor does not mean that every time you call it the same object gets returned. Rather, a new object will be returned every time. Just because both cars are green doesn't mean it's the same car.

ford === toyota // true

This is now true because both variables point to the exact same Car reference.

Community
  • 1
  • 1
Eli
  • 17,397
  • 4
  • 36
  • 49
5

First of all === is strict equality, not an identity operator, and Arrays, like objects are reference objects, not value objects as in the case of numbers and strings...

So when you are comparing those 2 arrays, you are creating two different arrays in memory. It'd be the same as saying...

var x = { a: 1 }; 
var y = { a: 1 };

x === y; //false  

You can't directly compare arrays or objects like that.

jcreamer898
  • 8,109
  • 5
  • 41
  • 56
3

because if it's not a primitive type (String, Number, Boolean), if it's an array or an object then the comparison operators will check if it's exactly the same instance. So

var a = ['as','ds'];
var b = a;
var c = ['as','ds'];
b == a; //will return true; (doesn't matter if it's == or === for non primitive types)
b == c; //will return false;

so basically you need to define your own method to compare arrays and see if all elements are the same. This sort of function usually doesn't exist because it can be very expensive and there's usually another way to write that sort of thing.

Damon Smith
  • 1,770
  • 18
  • 24
  • You're right that it doesn't matter for non-primitive, but you might always want to use `===` for the possibility that the types of the items being compared aren't guaranteed/known to be arrays. Not too important, just something to remember – Ian Dec 07 '12 at 05:06
  • In which case, it won't even bother attempting to compare values if the types don't match. I don't know, I think I'm confusing them now, I keep trying to think that over... – Ian Dec 07 '12 at 05:16
0

While array1==array2 doesn't seem to work (object identity equality),

Easiest option, works in almost all cases, except that null!==undefined but they both be converted to null and be considered equal:

function arraysEqual(a1,a2) {
    return JSON.stringify(a1)==JSON.stringify(a2);
}
Zaheer Ahmed
  • 28,160
  • 11
  • 74
  • 110