-3

I've always used

for( x in object ){}

but I just came accros

for( var x in object){}

I know the var matters in regular

for( var i=0;i<10;i++){}

statements, it bit me once in a recursive function, but does it matter when using for x in?...

lonewarrior556
  • 3,917
  • 2
  • 26
  • 55

1 Answers1

4

Re the var part:

Does it matter when using for x in?

Yes. It always matters to declare your variables. If you don't, and you're using loose mode, you fall prey to The Horror of Implicit Globals. (In strict mode, it's a nice detectable error. Use strict mode.) That will bite you in a recursive function, and in any of a large number of other non-recursive situations.

You don't have to declare it within the for construct, just make sure you declare it somewhere.


Re "Whats the proper way to iterate through an object?":

There are several proper ways. Like Mathletics, I'm partial to using Object.keys(...).forEach(...):

var obj = {
  a: "ay",
  b: "bee",
  c: "see"
};
Object.keys(obj).forEach(function(key) {
  snippet.log(key + ": " + obj[key]);
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Note that Object.keys will only look at the object's own properties, not the properties of its prototype.

The reason I like it is that it gives me a nice self-contained scope for what I'm doing on each "loop" iteration. If you're worried about the runtime cost of those callbacks, don't be.


But you can also just use a for in loop. If you do, you may or may not want to include hasOwnProperty, depending on whether you want to visit prototype properties.

var proto = {
  a: "ay (proto)",
  b: "bee (proto)",
  c: "see (proto)",
  d: "dee (proto)"
};
var obj = Object.create(proto);
obj.a = "ay";
obj.b = "bee";
obj.c = "see";

// Includes prototype properties if not shadowed by the object's own
snippet.log("for-in without hasOwnProperty");
var key;
for (key in obj) {
  snippet.log(key + ": " + obj[key]);
}

// Does not include prototype properties
snippet.log("for-in using obj.hasOwnProperty");
for (key in obj) {
  if (obj.hasOwnProperty(key)) {
    snippet.log(key + ": " + obj[key]);
  }
}

// If you're feeling paranoid about `obj` having had
// `hasOwnProperty` overridden, you can use it from `Object.prototype`:
snippet.log("for-in using Object.prototype.hasOwnProperty");
for (key in obj) {
  // Does not include prototype properties
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
    snippet.log(key + ": " + obj[key]);
  }
}
// I've never needed to do that in the real world, though
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Just don't use for-in on arrays without using appropriate safeguards; more about why (and your alternatives) in this answer.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875