I believe the answer you are looking for is linked in the accepted answer to the question you linked: http://www.jslint.com/help.html#forin
does not recommend use of the for in statement. Use Object.keys instead.
It goes on to explain why that is recommended.
Answer from Jack A. on Stack OverflowThe for in statement allows for looping through the names of all of the properties of an object. Unfortunately, it also loops through all of the properties that were inherited through the prototype chain. This has the bad side effect of serving up method functions when the interest is in data properties. If a program is written without awareness of this situation, then it can fail.
The body of every for in statement should be wrapped in an if statement that does filtering. It can select for a particular type or range of values, or it can exclude functions, or it can exclude properties from the prototype. For example,
for (name in object) { if (object.hasOwnProperty(name)) { .... } }Note that the above code will fail if the object contains a data property named hasOwnProperty. Use Object.keys instead.
Are nested for loops (in general - for loops) expensive in JavaScript? AFAIK prototype.map() is an alternative to for loop when it comes to code organisation but doesn't do well when memory, speed is taken into account. If for loops are expensive, what could be a performant alternative to nested for loop?
javascript - alternative to for loop - Stack Overflow
Alternative to for() loops?
javascript - Alternative for "for of"-loop - Stack Overflow
loops - Alternatives to javascript function-based iteration (e.g. jQuery.each()) - Stack Overflow
I believe the answer you are looking for is linked in the accepted answer to the question you linked: http://www.jslint.com/help.html#forin
does not recommend use of the for in statement. Use Object.keys instead.
It goes on to explain why that is recommended.
The for in statement allows for looping through the names of all of the properties of an object. Unfortunately, it also loops through all of the properties that were inherited through the prototype chain. This has the bad side effect of serving up method functions when the interest is in data properties. If a program is written without awareness of this situation, then it can fail.
The body of every for in statement should be wrapped in an if statement that does filtering. It can select for a particular type or range of values, or it can exclude functions, or it can exclude properties from the prototype. For example,
for (name in object) { if (object.hasOwnProperty(name)) { .... } }Note that the above code will fail if the object contains a data property named hasOwnProperty. Use Object.keys instead.
I'm not quite sure what you mean by "but this seems like a longer way to do it." Since you get to remove the hasOwnProperty check, it's actually, in some ways, much cleaner.
Here's an edited version that lints:
/*jslint browser */
/*global Pub */
// on a truthy match returns true and breaks from loop
Pub.someKey = function (obj, func, con) {
"use strict";
if (Pub.isFunction(func)) {
Object.keys(obj).forEach(function (key) {
if (func.call(con, obj[key], key, obj)) {
return true;
}
});
}
return false;
};
Pub.forSomeKey = Pub.someKey;
(I have a mild dislike of multiple return values, but edited this to use them to more closely match your original. And it gets rid of the "no breaks in forEach" issue I mentioned in the original.)
For more on why JSLint doesn't like for, see this Crockford video Setzer22 linked (in this question). It's interesting watching, and gives a little more context on why he doesn't like for... in specifically:
I've never liked
for... inbecause it does that stupid thing where it dredges through the prototype and you get all the methods and stuff that you didn't want. So now we've gotObject.keys, which returns an array of stuff and you don't get the dredge, and then pass that toforEachand its brothers, and it works great. So I don't usefor... inany more either.
Bonus tip: Watching Crockford at .5 speed while transcribing is hilarious, at least for a few minutes.
Aside: Unfortunately, @Oriol's and Matt Burland's comments don't hold, as I imagine @YeWhoseNameCantBeAtted found out. You can add the for directive to use standard for (i=0;...), but you'll still get Expected 'Object.keys' and instead saw 'for in' in this use case.
In anything except old IE (IE8 and older), you can do this:
["foo","bar","blah"].forEach(function(key) {
// do something
});
To add support in some versions of IE (I think IE7 and 8 allow this, IE6 does not):
if( ![].forEach) {
Array.prototype.forEach = function(callback) {
for( var i=0, l=this.length; i<l; i++) callback(this[i]);
};
}
Try to use Object.keys that will allow you to get only that part.
You can read more about here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
(Remember all associative arrays in javascript are objects)
Keep in mind is only supported on IE >= 9
Just a simple for loop should be quicker if you need to loop.
var l = collection.length;
for (var i = 0; i<l; i++) {
//do stuff
}
But, just because it's quicker doesn't mean it's always important that it is so.
This runs at the client, not the server, so you don't need to worry about scaling with the number of users, and if it's quick with a .each(), then leave it. But, if that's slow, a for loop could speed it up.
Ye olde for-loop