-
Notifications
You must be signed in to change notification settings - Fork 20.6k
Core: Make jQuery objects iterable #2369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
// unguarded in another place, it seems safer to just disable jsHint for these | ||
// three lines. | ||
/* jshint ignore: start */ | ||
if ( typeof Symbol === "function" && Symbol.iterator ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just check for Symbol
on the global instead of directly as a global?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we don't have a reference to the global, we only have reference to window
. In the browser they're equivalent but we also support running jQuery on Node (in a very basic way but still) where window
is a fake window object created by a library like jsdom.
To reference a global we'd need to pass an additional parameter to the jQuery factory... but that wouldn't work since if used with Browserify this
references the module and not the global. So we'd basically need to run a cascade test - check for the global
variable, fallback to this
. This wouldn't be shorter and would certainly be more fragile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I didn't realize we didn't have a reference to the global.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this check typeof Symbol.iterator === 'symbol'
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to worry about cases where a global Symbol is defined as a
function and Symbol.iterator doesn't have a typeof equal to "symbol"? I
imagine this would break using this code with Symbol polyfills that can't
override typeof.
Michał Gołębiowski
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and advocate for letting jQuery be exactly as iterable as arrays sharing its environment (and hence not to check for Symbol.iterator at all).
Almost agree. If there were an environment that implemented Symbol
, but hadn't implemented Symbol.iterator
yet, you'd end up with jQuery.fn.undefined = undefined
. If you don't care about that, then it's all good and I agree. Also, I don't know of any runtimes that match that, but for a few months both Chrome and Firefox did (obviously not anymore).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there were an environment that implemented
Symbol
, but hadn't implementedSymbol.iterator
yet, you'd end up withjQuery.fn.undefined = undefined
.
Correct. Or perhaps even something a little weirder, if Symbol.iterator
is partially implemented (e.g., by incomplete polyfill).
If you don't care about that, then it's all good and I agree.
Correct. I don't care about that, and here's why (edit mine):
I don't know of any runtimes [supported by jQuery] that match that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current situation is as follows:
- Latest stable Firefox, Chrome & Opera support
Symbol
,Symbol.iterator
&for-of
on any collections. - IE11 supports neither
Symbol
norfor-of
but Edge supports both. - Safari 8 doesn't support
Symbol
; it supportsfor-of
only on Arrays. WebKit Nightly supportsSymbol
,Symbol.iterator
&for-of
on any collections.
I don't think we're in a lot of danger that any browser will arrive with that much broken Symbol
global judging by the above info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mzgol as always, thank you for the thorough follow up
👏 This is so awesome. |
// three lines. | ||
/* jshint ignore: start */ | ||
if ( typeof Symbol === "function" && Symbol.iterator ) { | ||
jQuery.fn[ Symbol.iterator ] = [][ Symbol.iterator ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use arr
instead of []
.
PR updated, please re-review. |
@@ -10,3 +10,5 @@ | |||
|
|||
/dist | |||
/node_modules | |||
|
|||
/test/node_smoke_tests/lib/ensure_iterability.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could put it all in dist
and not add anything to .gitignore
or .jshintignore
but then I'd have to copy the entire test/node_smoke_tests
directory over as the ensure_iterability_es6.js
file requires files relative to its original location so transpiling to a different directory wouldn't fly.
"grunt-cli": "0.1.13", | ||
"grunt-compare-size": "0.4.0", | ||
"grunt-contrib-jshint": "0.10.0", | ||
"grunt-contrib-jshint": "0.11.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is required so that typeof x === "symbol"
works in esnext
mode.
|
||
if ( result !== "DIVSPANA" ) { | ||
console.error( "for-of doesn't work on jQuery objects; " + | ||
"expected: 'DIVSPANA'; got: '" + result + "'" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably use assert
, but I'm fine with a later sweep of node_smoke_tests
for that.
LGTM 👍 |
I'll land this shortly barring any new remarks. |
Utilize the assert module, avoid inline JSHint comments.
Make iterating over jQuery objects possible using ES 2015 for-of: for ( node of $( "<div id=narwhal>" ) ) { console.log( node.id ); // "narwhal" } Fixes jquerygh-1693
Make iterating over jQuery objects possible using ES 2015 for-of:
Fixes gh-1693
TODO:
core-js
-polyfilledSymbol
&Symbol.iterator
.Symbol.iterator
check, leave just thetypeof Symbol
one.[][Symbol.iterator]
toarr[Symbol.iterator]
.UseJust use theQUnit.skip
to skip the test in non-ES6 browsers.ok
assertions in non-ES6 browsers.@rwaldron, could you have a look if it's safe to include this in 3.0.0?