Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Javascript, why is [1, 2] == [1, 2] or ({a : 1}) == ({a : 1}) false? [duplicate]

Tags:

javascript

The following is done in Firebug:

>>> [1, 2] == [1, 2]
false

>>> ({a : 1}) == ({a : 1})
false

I thought Javscript has some rule that says, if an Object or Array has the same references to the same elements, then they are equal?

But even if I say

>>> foo = {a : 1}
Object { a=1}

>>> [foo] == [foo]
false

>>> ({a: foo}) == ({a: foo})
false

Is there a way to make it so that it can do the element comparison and return true?

like image 928
nonopolarity Avatar asked Oct 10 '11 13:10

nonopolarity


People also ask

Why == is false in JavaScript?

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

Why comparing two JavaScript objects will always return false?

Comparing two objects like this results in false even if they have the same data. It is because those are two different object instances, they are referring to two different objects. There is no direct method in javascript to check whether two objects have the same data or not.

Why are objects not equal JavaScript?

In JavaScript, objects are a reference type. Two distinct objects are never equal, even if they have the same properties. Only comparing the same object reference with itself yields true. For more information about comparison operators, see Comparison operators.

What does $() mean in JavaScript?

Usually when you encounter $() , that means the developer is using a javascript library, such as jQuery. The $ symbol is the namespace for those libraries. All the functions they define begin with $. , such as $. get() .


1 Answers

{ } and [ ] are the same as new Object and new Array

And new Object != new Object (ditto with Array) because they are new and different objects.

If you want to know whether the content of two arbitary objects is the "same" for some value of same then a quick (but slow) fix is

JSON.parse(o) === JSON.parse(o)

A more elegant solution would be to define an equal function (untested)

var equal = function _equal(a, b) {
  // if `===` or `==` pass then short-circuit
  if (a === b || a == b) { 
    return true;
  }
  // get own properties and prototypes
  var protoA = Object.getPrototypeOf(a), 
      protoB = Object.getPrototypeOf(b),
      keysA = Object.keys(a), 
      keysB = Object.keys(b);

  // if protos not same or number of properties not same then false
  if (keysA.length !== keysB.length || protoA !== protoB) {
    return false;
  }
  // recurse equal check on all values for properties of objects
  return keysA.every(function (key) {
    return _equal(a[key], b[key]);
  });
};

equals example

Warning: writing an equality function that "works" on all inputs is hard, some common gotchas are (null == undefined) === true and (NaN === NaN) === false neither of which I gaurd for in my function.

Nor have I dealt with any cross browser problems, I've just assumed ES5 exists.

like image 144
Raynos Avatar answered Oct 20 '22 17:10

Raynos