documentcloud/underscore — Issue #329: Newest _.isEqual creates incompatibility with Backbone.Relational (and more!)
Author: kmalakoff
Created: 2011-10-09 10:15:52+00:00
State: open

Hello,

The newest _.isEqual introduces an incompatibility with Backbone.Relational, but it could be more wide-spread. I'm not sure if this bug should go here or in Backbone, you can decide!

The new check in eq() introduces array comparisons:
if (a.length === +a.length || b.length === +b.length)

Backbone.Collection reset() sets a length variable:
this.length = 0;

And Backbone.Model set() checks for a change in attribute using:
if (!_.isEqual(now[attr], val))

Finally, Backbone.Relational replaces the serialized json arrays with a collection using Backbone.Model set(), but with the new _isEqual and the length variable on the Collection, when you pass an empty array with length = 0, the set doesn't occur because _.isEqual incorrectly detects that they are equal, even though one is an array and the other is a Backbone.Collection.

So I think the new _isEqual will incorrectly say anything is equal with zero length because of the new test:
if (a.length === +a.length || b.length === +b.length)

I'm really not sure what the right fix is. Is it introducing a special case for "array-like" objects of zero length? Is it adding a check that something is a "pure"-array like object (no properties)?

Either way, there should be a test like equal(_.isEqual(new Backbone.Collection(), []), false, 'Backbone.Collection is array-like, but also has properties'), but without the dependency on Backbone.

If this isn't clear, please let me know.

Cheers!