Object.isArray should be changed

19 views
Skip to first unread message

buda

unread,
Oct 23, 2011, 1:25:36 AM10/23/11
to prototype-s...@googlegroups.com
I've noticed that library's isArray not worked properly sometimes.
I offer new version of it

isArray: function(obj) {
return (typeof(obj) === 'object') && !Object.isUndefined(obj.forEach);
}

T.J. Crowder

unread,
Oct 23, 2011, 7:54:42 AM10/23/11
to Prototype & script.aculo.us
On Oct 23, 6:25 am, buda <www...@pochta.ru> wrote:
> I've noticed that library's isArray not worked properly sometimes.

When? A statement like that really requires data. I suspect where you
haven't seen it work, the object genuinely isn't an array.

Prototype's `Object.isArray` function relies on the JavaScript engine
correctly implementing the specification for
`Object.prototype.toString` (Section 15.2.4.2[1]). I've never met an
engine that didn't implement that correctly. In contrast, your
implementation gives false negatives on any browser that hasn't yet
implemented the new `forEach` array prototype method from ECMAScript5
(so, IE8 and downward), and gives false positives on any object that
just happens to have a property called `forEach`. Respectfully, the
Prototype implementation is much more robust.

[1] http://es5.github.com/#x15.2.4.2
--
T.J. Crowder
Independent Software Engineer
tj / crowder software / com
www / crowder software / com

T.J. Crowder

unread,
Oct 23, 2011, 8:04:35 AM10/23/11
to Prototype & script.aculo.us
Hi again,

Sorry, I was talking about Prototype 1.7's version of `isArray`. I
suddenly had a thought just now, so I checked and found that Prototype
1.6 used a different (and naive) definition which has known issues;
presumably those issues are why 1.7's version has been updated. So if
you're using 1.6, you may well see a false negative on a real array
instance. (Specifically, any array received from another window will
result in a false negative.) I'm surprised that 1.6 had that problem,
but it's good to see that 1.7 fixes it.

If you want to apply the fix to your projects without upgrading from
1.6 to 1.7, here's a cheap and easy way:

(function() {
var toString = Object.prototype.toString;
Object.isArray = function(obj) {
return toString.call(obj) === "[object Array]"; //
Capitalization matters
};
})();

HTH,
--
T.J. Crowder
Independent Software Engineer
tj / crowder software / com
www / crowder software / com

Reply all
Reply to author
Forward
0 new messages