-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Implements the JavaScript Iterable protocol. #4061
Conversation
What I don't like about this is the fallback use of I know this has caused some bugs in Ramda (a lib implementing this style too). I'm fine with it being a modern only enhancement (that's what |
That's definitely a concern to weigh. I'm curious to know more about the issues Ramda encountered. I would be surprised if Another potential approach to avoid inconsistency is to always define An unfortunate issue of only implementing Iterable when Symbol is defined is the potential for inconsistent behavior between browsers when in use with libraries that support the fallback (Ramda being a fine example). |
Naw, there wouldn't be an issue because Backbone wouldn't have the fallback so it wouldn't be detected in those libs. If folks really want support there's |
I agree with JDD, only export iterators if |
|
||
// Construct a value depending on what kind of values should be iterated. | ||
var value; | ||
if (this._kind === 'value') { |
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 think I'd rather define an enum of kinds rather than use strings but not strongly opposed to this
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 you have a preferred enum style in mind? I don't feel strongly about this, happy to take suggestions.
Thanks for the issues, @jdalton that's informative. I don't think those apply here - those issues are about consuming iterables rather than implementing them. The issue there is that ramda was detecting iterables by looking for Symbol.iterator if it exists, but only falling back to For libraries that implement iterable, there's very little downside to using the fallback. Libraries consuming iterables which only look for Symbol.iterator would behave identically when given an Iterable which does or doesn't use the fallback. Older versions of Firefox will suddenly work correctly (which support Iterables but use the pseudo-symbol). Libraries which look for both will benefit from having iterables define the fallback without requiring es6-shim or core-js. The downside is that there is an additional prototype method defined which, as you mentioned, appears if you Object.keys() the prototype. Anyhow, I can remove it since you both feel strongly about it. Supporting Iterable in ES6 (or shimmed) environments is still great even without using the fallback pseudo-symbol. |
|
||
var KIND_VALUE = 1; | ||
var KIND_KEY = 2; | ||
var KIND_KEY_VALUE = 3; |
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.
@megawac let me know if you prefer this enum style over strings
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.
Yep, I prefer this for sure. Mind renaming these ITERATOR_VALUEs
, ITERATOR_KEYS
, ITERATOR_KEYVALUES
Let's avoid the potential headache, user or otherwise, anyway.
User adoption of new FF releases is pretty fast. The
Great! As a result of this PR I've updated Lodash's checks to allow shims too. |
🎉 |
LGTM, I'll defer to another contrib to merge /cc @jridgewell @akre54 |
value = model; | ||
} else { | ||
var id = this._collection.modelId(model.attributes); | ||
if (this._kind === ITERATOR_KEYS) { |
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.
another option to using these enums to indicate what to place as value would be to have the values
, keys
, and entries
pass a function(model, collection)
to define the value. I'm fine with this either way.
Looks great. Thanks @leebyron! I think we're at the point where if you need this you're probably targeting evergreen browsers anyways. We can reassess if anyone feels particularly strongly. |
This introduces new methods related to Iterators on Backbone.Collection to mirror those found on Array: `values`, `keys`, `entries`, and `@@iterator`. Each of these methods will return a JavaScript Iterator, which has a `next` method, yielding the models or ids of models contained in the Collection. The CollectionIterator is careful to use the `at()` and `modelId()` methods on the host collection rather than direct access to the `models` property, which should ensure it is resilient to creative subclassing of Backbone.Collection and future feature addition. The [`@@iterator`](http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols) method is defined using `Symbol.iterator` if it exists in the JavaScript runtime (modern browsers/node.js) and falls back to the string `"@@iterator"` which was popularized by older versions of Firefox and has become the standard fallback behavior for other third-party libraries. This ensures that Backbone can still be used across all browsers, even with use of these new methods. Supporting Iterable allows better integration between Backbone and the most recent additions to the JavaScript language, including `for of` loops and data-collection constructor functions, as well as better integration with other third-party libraries that accept Iterables instead of only Arrays. Fixes jashkenas#3954
I dig it. 👍 |
This introduces new methods related to Iterators on Backbone.Collection to mirror those found on Array:
values
,keys
,entries
, and@@iterator
. Each of these methods will return a JavaScript Iterator, which has anext
method, yielding the models or ids of models contained in the Collection.The CollectionIterator is careful to use the
at()
andmodelId()
methods on the host collection rather than direct access to themodels
property, which should ensure it is resilient to creative subclassing of Backbone.Collection and future feature addition.CollectionIterator's
next
method follows the same algorithm defined by ES6 for ArrayIterator'snext
.The
@@iterator
method is defined usingSymbol.iterator
if it exists in the JavaScript runtime (modern browsers/node.js) and falls back to the string"@@iterator"
which was popularized by older versions of Firefox and has become the standard fallback behavior for other third-party libraries. This ensures that Backbone can still be used across all browsers, even with use of these new methods.Supporting Iterable allows better integration between Backbone and the most recent additions to the JavaScript language, including
for of
loops and data-collection constructor functions, as well as better integration with other third-party libraries that accept Iterables instead of only Arrays.Fixes #3954