jashkenas/underscore

_.keys is inconsistent for arguments-type objects

dark-panda opened this issue · 1 comments

_.keys returns an empty array when called on arguments object on some browsers regardless of the arguments passed to the function, while on other browsers it is returning an array filled with the stringified keys as taken from the arguments object.

For instance:

(function() {
  return _.keys(arguments);
}('one', 'two', 'three'));

Produces the following in Firefox 8, Chrome 15 and Opera 11 and the current WebKit nightly build:

["0", "1", "2"]

While on IE 8 and Safari 5.1, we see an empty array:

[]

This seems to be a combination of how the various browsers implement Object.keys and how they handle arguments objects.

  • Firefox, Chrome and Safari implement Object.keys, but older versions of Safari don't consider the array-like indexes in arguments objects to be enumerable.
  • Opera doesn't seem to implement Object.keys, but the fall-back implementation for _.keys works as expected as Opera handles arguments objects like Firefox and Chrome do.
  • IE 8 doesn't implement Object.keys and seems to act like Safari in how it handles arguments objects. I believe IE 9 does implement Object.keys, but I don't have an IE 9 box available to test how it handles arguments in this situation.
  • WebKit is currently doing the right thing as of https://bug-70302-attachments.webkit.org/attachment.cgi?id=111378 so presumably a fix in Safari will be right around the corner.

According to ECMA-262 5th Edition, section 10.6, the keys set in the arguments object are supposed to be set to Enumerable, so it seems that at least IE 8 and below and Safari 5.1 and below are behaving badly here.

Yep -- browsers will be browsers.

If you'd like to have more reliable behavior, I'd recommend turning the arguments object into a real array before working on it:

_.keys(_.toArray(arguments));