Reputation: 2775
Consider this object: var obj = {10: 0, 11: 1, 12: 2};
Using the method Object.keys(obj)
, you can see that obj
has three keys: 10,11,12.
However, if you wanted to iterate over each key (for example, in order to get the value for each key), a standard for loop returns the correct keys, but the "for in" style does not. Does anyone know what's going on here? Is it possible to get the correct key names using "for in"?
JSFiddle: http://jsfiddle.net/n7sm22kb/
Upvotes: 2
Views: 2209
Reputation: 41
I suspect @jlewkovich wanted to use
for (key of Object.keys(obj)) {
rather than:
for (key in Object,keys(obj)) {
Notice of rather than in. I say that because I found this page after making that mistake.
PS: I tried to add this as a comment, but don't have the reputation points, so please forgive a new answer where I think a comment would have been more appropriate. @ssube answered the question. This is an answer to a different question I think the author would have liked to ask.
Upvotes: 1
Reputation: 48327
In your specific example, this is because Object.keys
returns an array. for ... in
and Object.keys
do very similar things, so you're iterating over the keys of the array of keys, hence your problem.
You can see this by running:
var obj = {10: 0, 11: 1, 12: 2};
var keys = Object.keys(obj); // ['10', '11', '12'];
for (var key in keys) {
console.log('Keys has', keys[key], 'at', key);
}
The proper equivalent using for ... in
would be more like:
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(obj[key]);
}
}
You can see the additional complexity introduced here.
for ... in
(#12.6.4 in the spec) loops over all enumerable properties in the object, including ones inherited from the prototype, causing it to include a lot of stuff you may need to filter out. In the case of an array, it loops over the property names (i.e., array indices) of each item in the array. This is the second level of indirection you're running into problems with.
Object.keys
(#15.2.3.14 in the spec) is defined to only retrieve keys from the object itself ("For each own enumerable property..."), saving you the need for that check.
When possible, prefer Object.keys
in most cases, as it saves you the logic. If [].forEach
is available, you can also use that:
Object.keys(obj).forEach(function (key) {
console.log('Object has', obj[key], 'at', key);
});
Upvotes: 4