Skip to main content

Bug Tracker

Side navigation

#14649 closed bug (notabug)

Opened December 22, 2013 01:34PM UTC

Closed December 24, 2013 02:18PM UTC

isArrayLike throws on strings (should return false)

Reported by: Nigel Owned by: rwaldron
Priority: undecided Milestone: None
Component: unfiled Version: 2.0.3
Keywords: Cc: gibson042
Blocked by: Blocking:
Description

If you call isArrayLike with a string then it should return false, instead it throws an error (e.g. passing the string 'foonana'):

"TypeError: Cannot use 'in' operator to search for '6' in foonana"

Attachments (0)
Change History (11)

Changed December 22, 2013 05:15PM UTC by rwaldron comment:1

owner: → rwaldron
status: newassigned

Changed December 22, 2013 05:24PM UTC by rwaldron comment:2

cc: → gibson042

We could/should add a check for type === "string" here: https://github.com/jquery/jquery/blob/master/src/core.js#L495 which would make jQuery's "array-like" checking future-friendly with emerging language additions, ie. String.prototype.@@iterator, Array.from(string), etc.

Before I go ahead with this, I want Richard to sign off on my rationale above

Changed December 22, 2013 05:55PM UTC by gibson042 comment:3

isArrayLike is a private function, and as far as I can tell never receives string input from valid public calls. So my default position is to oppose changes until seeing a demonstration warranting such.

Changed December 22, 2013 07:28PM UTC by rwaldron comment:4

Replying to [comment:3 gibson042]:

isArrayLike is a private function, and as far as I can tell never receives string input from valid public calls. So my default position is to oppose changes until seeing a demonstration warranting such.

Good call and agreed.

Changed December 23, 2013 10:08AM UTC by Nigel comment:5

Replying to [comment:4 rwaldron]:

Replying to [comment:3 gibson042]: > isArrayLike is a private function, and as far as I can tell never receives string input from valid public calls. So my default position is to oppose changes until seeing a demonstration warranting such.

It means whenever you call $.map or other functions that use isArrayLike you get a horrible error message back. The extra overhead of checking for string is surely negligible for a better return value?

Changed December 23, 2013 01:59PM UTC by markelog comment:6

Replying to [comment:5 Nigel]:

Replying to [comment:4 rwaldron]: > Replying to [comment:3 gibson042]: > > isArrayLike is a private function, and as far as I can tell never receives string input from valid public calls. So my default position is to oppose changes until seeing a demonstration warranting such. > It means whenever you call $.map or other functions that use isArrayLike you get a horrible error message back. The extra overhead of checking for string is surely negligible for a better return value?

Could you please provide a test case using public jQuery API? You could use jsfiddle or similar service for that.

Changed December 23, 2013 02:46PM UTC by dmethvin comment:7

It means whenever you call $.map or other functions that use isArrayLike you get a horrible error message back.

There are no guarantees what you'll get back when you call an API method with incorrect arguments.

Changed December 23, 2013 11:05PM UTC by anonymous comment:8

Replying to [comment:6 markelog]:

Could you please provide a test case using public jQuery API? You could use jsfiddle or similar service for that.

just call $.map with a string: http://jsfiddle.net/aH4mU/

Changed December 23, 2013 11:14PM UTC by Nigel comment:9

Replying to [comment:7 dmethvin]:

> It means whenever you call $.map or other functions that use isArrayLike you get a horrible error message back. There are no guarantees what you'll get back when you call an API method with incorrect arguments.

isArrayLike, even as a private function, should (IMHO) not throw an exception if passed a non array - it should return false. Surely the whole point of having it is to check if it is array like and do something else if not?

Though in its current form it probably blows up if the argument doesn't have a length property anyway.

Changed December 23, 2013 11:18PM UTC by Nigel comment:10

Sorry - make that http://jsfiddle.net/aH4mU/1/

Changed December 24, 2013 02:18PM UTC by gibson042 comment:11

resolution: → notabug
status: assignedclosed

Replying to [comment:8 anonymous]:

just call $.map with a string: http://jsfiddle.net/aH4mU/

jQuery.map accepts arrays and objects, not strings.

Replying to [comment:9 Nigel]:

isArrayLike, even as a private function, should (IMHO) not throw an exception if passed a non array - it should return false. Surely the whole point of having it is to check if it is array like and do something else if not?

The whole point of having it is to identify those objects that should be iterated over by numeric index, generally to differentiate them from objects that should be iterated over with for...in loops. We take pains to ''avoid'' passing in strings, and if you circumvent that by calling jQuery methods with invalid input, then (as [comment:7 dmethvin] said) "There are no guarantees what you'll get back".

And although we'd never add code to guarantee it, I consider throwing exceptions when a call steps outside the bounds of our documented API to be ''better'' behavior than silently propagating misconceptions.