The thing that shocks me most in this article is the subtleness of the bug inducing this behaviour: <a href="http://trac.webkit.org/changeset/182058" rel="nofollow">http://trac.webkit.org/changeset/182058</a>
I didn't realize anyone used integers as keys. That feels so unnatural to me. I'm also surprised any libraries would check for .length to see if it's an array or not; there are plenty of objects you may want to create with a length property. It seems to me this would be a more accurate check:<p>Object.prototype.toString.call(maybeArray) === "[object Array]"<p>Also sometimes I feel like I'm the only one who doesn't like to use underscore or jQuery for things like this; iterating over properties is so easy it seems weird to me to use a library to create a new object for me to then iterate through.
I came across an equally strange bug a year or so ago.<p><a href="http://stackoverflow.com/questions/22139746/ios-javascript-engine-parsefloat1-returns-negative-number/22159620#22159620" rel="nofollow">http://stackoverflow.com/questions/22139746/ios-javascript-e...</a><p>I found a way to reproduce it, put in a bug report with apple and never got a response.
The workaround in the article was:<p><pre><code> var thingsGroupedById = _.groupBy(things, function(t){
return 'seller' + t.sellerId
});
// { seller1: [...], seller2: [...] }
</code></pre>
But I actually would have failed this in code review:<p><pre><code> _.map(thingsGroupedById, function (things) {
// ...
});
</code></pre>
and replaced it with:<p><pre><code> _.map(_.keys(thingsGroupedById), function (thingKey) {
var thing = thingsGroupedById[thingKey];
// ...
});
</code></pre>
because although mapping over objects is "normal", it has never been 100%.
I ran into this bug myself, and I spent an afternoon or so debugging it.<p>A simple library upgrade (Underscore 1.7.0 -> 1.8.2) broke a key feature of a site I was working on, but only on my iPhone. It worked just fine on my iPad running the <i>same exact</i> version of iOS.<p>I ended up using git bisect to narrow down the commit, which consisted of several minor updates to various packages. Of those packages, it was my 3rd or 4th guess as to which would have caused that failure (it wasn't clear since I was having trouble connecting the Safari debugger).
Array.isArray() would be more reliable than testing if it has a property "length" :/<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray" rel="nofollow">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...</a>
For an equally crazy bug that's affecting Angular and several other major libraries:<p><a href="https://github.com/angular/angular.js/issues/9128#issuecomment-77524687" rel="nofollow">https://github.com/angular/angular.js/issues/9128#issuecomme...</a><p>Basically strict mode blows up webkit in odd ways.
I noticed an instance of _.size(obj) returning "undefined" on a collection using number indices, but in each instance_.keys(obj).length would work fine.<p>This was occurring on iOS 7.1.2 on a single device, from time to time. I realize after reading this, that this might be related to the WebKit bug, since it was the only 64 bit ARM device we had at the time.<p>The bug disappeared when I simply used _.keys(obj).length instead of _.size(obj). It was very hard to reproduce and I could never isolate it in a sample...<p>It's NOT the same bug though. It's kind of the opposite. The "length" property would disappear. Would that be caused by the same WebKit bug? Or that's a new one?
Not to be a jerk, but why not use objects for key value and arrays for int value?<p>Yes, JavaScript object/array system has it's warts, but to me that's clearly the way it was intended to be used.