Seems like it's reinventing the natively-provided wheel, doesn't it? Is it really worth extra framework weight? Why do those frameworks feel the need to define it as an additional feature when for...in
seems to serve the feature's purpose just fine?

- 29,891
- 5
- 68
- 79

- 6,867
- 9
- 32
- 42
-
All the answers are great. Tthey all add different insights, so give them all a read if you see this. – wwaawaw Sep 15 '12 at 13:36
4 Answers
There are some good reasons to avoid using for..in
to iterate over arrays.
$.each
and _.each
stand in prior to the introduction of Array.forEach
in Javascript 1.6.
-
Right, which is why I'm not asking about `Arrary.forEach`, but instead `for..in`, which seems to have widespread compatibility. The linked thread was pretty good. That said, given that I can't control what libraries are loaded on the page, would there be any way of escaping the potential additions to `Object.prototype`? Could I change the `Object` instance's `__proto__` to something else? I suppose not anything that wouldn't still be a descendant of `Object` though, right? How does the `hasOwnProperty` trick work? – wwaawaw Sep 05 '12 at 07:00
-
1Most (all?) of the Underscore methods delegate the to native ones when available. And `_.each` and friends work on non-Array objects as well as Arrays. – mu is too short Sep 05 '12 at 16:47
-
Yes, again, I was asking about `for...in`, and NOT `forEach`. I'm working with non-array objects. – wwaawaw Sep 06 '12 at 08:23
For example if you do something like this:
for (var i = 0; i < 5; i += 1) {
document.getElementById('el' + i).onclick = function () {
alert(i);
};
}
Then if you will click on every element you will get 5
because it catch context, and i
variable is the same in each case.
It can be fixed this way:
for (var i = 0; i < 5; i += 1) {
(function (i) {
document.getElementById('el' + i).onclick = function () {
alert(i);
};
})(i);
}
But with each
it is better, so when you do (not good example but just for demonstration):
$('.el').each(function (i) {
$(this).click(function () { alert(i); });
});
Then it works fine, because when you pass a variable in function then context is lost.

- 29,891
- 5
- 68
- 79
-
@adlwalrus -- It is well worth reading up on how closures and anonymous functions worth so you can understand what is going on behind the scenes of many of these libraries. – Jeremy J Starcher Sep 05 '12 at 06:44
-
@SperanskyDanil Nothing is passed by reference in JS. Objects just have a reference as their value. – alex Sep 05 '12 at 06:45
for ... in
also catches properties down the prototype chain. You have to use the .hasOwnProperty()
method to filter things out.

- 23,369
- 6
- 54
- 74
-
Could you give an example of how to do this? I had a thought to somehow reassign the object's prototype to something different, like, say, `oogabooga` but I still can't escape its `Object`-hood, so that seems like it would never work as a strategy. I can't be sure what other libraries there are on the page that might alter `Object.prototype` – wwaawaw Sep 05 '12 at 06:53
-
You'll have to google the rest, but in short: `Object.prototype.testValue = "Nana";` then take any [native] object and try a `window.alert({}.testValue)` The `testValue` property now shows up in every single object and you need extra code to filter it out. That is what is wrong with `for ... in` – Jeremy J Starcher Sep 05 '12 at 06:58
-
The inheritance issue
can be solved with:
for (key in obj) {
if(obj.hasOwnProprty(key)) continue;
console.log("Property "+key+" has value "+obj[key].toString());
}
I've seen some on the tubes use:
if (Object.prototype.hasOwnProperty(key)) continue;
...for the hasOwnProperty
filter, but I don't think that it's inherently any more safe, and if you're including code that's modified an object's hasOwnProperty
property on your page, then IDK what to tell you anyway, except that the code's right there^^ if you want it, and to find a new library to start working with. I mean, if someone can modify your object's hasOwnProperty
property, then what's to stop them from modifying Object.prototype.hasOwnProperty
as well?
Anyhow, some relevant links to the inherited property issue:
http://javascript.info/tutorial/native-prototypes
http://javascript.info/tutorial/inheritance
I really wish someone would give the javascript.info
dude a hand maintaining the english version of his tutorial, because it's really fantastic.
Another issue with for...in
...is that you theoretically aren't guaranteed the iteration order. If you're dealing in an array, it isn't necessarily in ascending or even descending order of the indices. The spec leaves it to vendors to decide. In practice I've read that it's more/less uniform and predictable, but that isn't guaranteed is all.

- 6,867
- 9
- 32
- 42