Loop Through Array inside Object in Javascript [duplicate] - javascript

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Loop through Json object
{
"data": [
{
"name": "Jen",
"id": "1"
},
{
"name": "Steve",
"id": "8"
}
]
}
A server I'm interacting with responds with the above.
I'm trying to loop through itenter code here for the For..in statement.
This is what I'm trying to do:
for (var item in response.data) {
console.log(item.name);
}
This doesn't work.
What went wrong?
Thank you
I GOT IT to work with the following after reading the comment:
for (var item in response.data) {
console.log(response.data[item].name);
}
I was able to get a list of names...
Can someone dissect the response as to why it worked?

data is actually an array (denoted by []), rather than an object so you want a regular for loop rather than a for in.
for (var i = 0; i<response.data.length; i++) {
// use i as an array index
console.log(response.data[i].name);
}
In JavaScript, the for in construct is used for iterating over object properties, but to iterate an array an incremental for loop is typically used.

Check out: Why is using "for...in" with array iteration a bad idea?
For...in iterates through names of the properties of an object. Array items are also considered "properties", so for..in iterates through indexes (which are 0, 1 in your case). As expected when you use response.data[0] you get first element of your array.

for..in iterates over the enumerable properties of an object in no particular order (you may get a different order in different browsers). An array is just a plain object with a special length method and handy methods inherited from Array.prototype (some of which depend on the special length property). There is no restriction on what can be used for a property name, they are not restricted to non-negative integers (noting that where a properly name is not a valid identifier, square bracket notation must be used to access its value).
The indexes of an array are just string property names (i.e. they are just plain object property names) that are non-negative integers, so a for..in loop will iterate over the numeric indexes (again, not necessarily in ascending or descending order) as well as all other enumerable properties, including those on the [[Prototype]] chain. Therefore it is always recommended to include a hasOwnProperty test with for..in unless you want to include inherited enumerable properties.
Because of the above, it is generally much better to iterate over array properties using a counter from 0 to array.length - 1 (since the length is always one bigger than the last index).
To test the "no particular order" statement, try the following in IE and other browser and note the different order:
var a = [];
a[2] = 2;
a[0] = 0;
a[3] = 3;
var b = [];
for (var i in a) b.push(a[i]);
alert(b);

Related

Javascript: For in loops iterating over properties or indices?

Just started learning Javascript. Recently I used a for-in loops to iterate over properties of an object. For example...
var someObject = { a:1, b:2 };
for(var property in someObject){
console.log(property);
}
This would print...
"a"
"b"
However, when I use it to iterate over an array...
var someArray = ["a","b","c"];
for(var element in someObject){
console.log(element);
}
The indices, rather than the elements, get printed...
"0"
"1"
"2"
Why is this the case? In general, do JS for-in loops print properties only when iterated over objects and indices for everything else?
If it prints indices with the exception of objects, why would one ever use a classic for loop such as
for(var i=0,i<someNumber,i++)
when one can just use a for in loop? Especially since this seems a lot more concise?
for(var i in something)
Am I even supposed to use for-in loops for anything besides objects?
Thanks!
Quoting from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Description
for..in should not be used to iterate over an Array where index order
is important. Array indexes are just enumerable properties with
integer names and are otherwise identical to general Object
properties. There is no guarantee that for...in will return the
indexes in any particular order and it will return all enumerable
properties, including those with non–integer names and those that are
inherited.
Because the order of iteration is implementation dependent, iterating
over an array may not visit elements in a consistent order. Therefore
it is better to use a for loop with a numeric index (or Array.forEach
or the non-standard for...of loop) when iterating over arrays where
the order of access is important.
So, Don't rely on for..in for iterating over an Array.
And to answer
The indices, rather than the elements, get printed... Why is this the
case?
The answer has already been quoted above.
Array indexes are just enumerable properties with integer names and
are otherwise identical to general Object properties.
To confirm that fact, try the following sample code
var myArray = ["A", "B", "C"];
for (var i = 0; i < 3; i += 1) {
console.log(myArray.hasOwnProperty(i)); // will print true
}
That is why for..in works with Arrays as well.

Getting the key of an array item while in a numerically indexed loop [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
For..In loops in javascript - key value pairs
I need to loop through an array in order, just like in this question. However, I also need to get access to the key name. How can I do that while in a numerically indexed loop?
for(i=0; i<arr.length; i++){
alert(arr[i].key); // clearly won't work
}
but
for(key in arr){
alert(arr[key]); // works, but it doesn't loop through in the right order
}
You cannot list through an JavaScript object's properties and expect them to be returned in a particular order.
Read this blog post and check out the part about for loop order.
If you want to "sort" an object, then you can put the key names in an array, sort that, then access the object properties in the order they are in the array, e.g.:
var obj = { '3':3, '0':0, '2':2, '1':1};
var props = [];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
props.push(p);
}
}
props.sort();
for (var i=0, iLen=props.length; i<iLen; i++0 {
alert(obj[props[i]]); // 0, 1, 2, 3
}
In regard to the order of object properties, ES5 says:
The mechanics and order of enumerating the properties (step 6.a in the
first algorithm, step 7.a in the second) is not specified.
http://es5.github.com/#x12.6.4
You may discover in the comments of a popular library the statement "Own properties are enumerated firstly", which is contradicted by the behaviour of at least one widely used browser and therefore should be disregarded.

JavaScript Loops: for...in vs for

I faced a strange behaviour in Javascript. I get
"Object doesn't support this property or method"
exception for the removeAttribute function in the following code:
var buttons = controlDiv.getElementsByTagName("button");
for ( var button in buttons )
button.removeAttribute('disabled');
When I change the code with the following, the problem disappears:
var buttons = controlDiv.getElementsByTagName("button");
for ( var i = 0; i < buttons.length; i++ )
buttons[i].removeAttribute('disabled');
What is the value of button inside the for...in?
Don't use for..in for Array iteration.
It's important to understand that Javascript Array's square bracket syntax ([]) for accessing indicies is actually inherited from the Object...
obj.prop === obj['prop'] // true
The for..in structure does not work like a more traditional for..each/in that would be found in other languages (php, python, etc...).
Javascript's for..in is designed to iterate over the properties of an object. Producing the key of each property. Using this key combined with the Object's bracket syntax, you can easily access the values you are after.
var obj = {
foo: "bar",
fizz: "buzz",
moo: "muck"
};
for ( var prop in obj ) {
console.log(prop); // foo / fizz / moo
console.log(obj[prop]); // bar / buzz / muck
}
And because the Array is simply an Object with sequential numeric property names (indexes) the for..in works in a similar way, producing the numeric indicies just as it produces the property names above.
An important characteristic of the for..in structure is that it continues to search for enumerable properties up the prototype chain. It will also iterate inherited enumerable properties. It is up to you to verify that the current property exists directly on the local object and not the prototype it is attached to with hasOwnProperty()...
for ( var prop in obj ) {
if ( obj.hasOwnProperty(prop) ) {
// prop is actually obj's property (not inherited)
}
}
(More on Prototypal Inheritance)
The problem with using the for..in structure on the Array type is that there is no garauntee as to what order the properties are produced... and generally speaking that is a farily important feature in processing an array.
Another problem is that it usually slower than a standard for implementation.
Bottom Line
Using a for...in to iterate arrays is like using the butt of a screw driver to drive a nail... why wouldn't you just use a hammer (for)?
for...in is to be used when you want to loop over the properties of an object. But it works the same as a normal for loop: The loop variable contains the current "index", meaning the property of the object and not the value.
To iterate over arrays, you should use a normal for loop. buttons is not an array but a NodeList (an array like structure).
If iterate over buttons with for...in with:
for(var i in a) {
console.log(i)
}
You will see that it output something like:
1
2
...
length
item
because length and item are two properties of an object of type NodeList. So if you'd naively use for..in, you would try to access buttons['length'].removeAttribute() which will throw an error as buttons['length'] is a function and not a DOM element.
So the correct way is to use a normal for loop. But there is another issue:
NodeLists are live, meaning whenever you access e.g. length, the list is updated (the elements are searched again). Therefore you should avoid unnecessary calls to length.
Example:
for(var i = 0, l = buttons.length; i < l, i++)
for(var key in obj) { } iterates over all elements in the object, including those of its prototypes.
So if you are using it and cannot know nothing extended Object.prototype you should always test obj.hasOwnProperty(key) and skip the key if this check returns false.
for(start; continuation; loop) is a C-style loop: start is executed before the loop, continuation is tested and the loop only continues while it's true, loop is executed after every loop.
While for..in should not generally be used for Arrays, however prior to ES5 there was a case for using it with sparse arrays.
As noted in other answers, the primary issues with for..in and Arrays are:
The properties are not necessarily returned in order (i.e. not 0, 1, 2 etc.)
All enumerable properties are returned, including the non–index properties and those on the [[Prototype]] chain. This leads to lower performance as a hasOwnProperty test is probably required to avoid inherited properties.
One reason to use for..in prior to ES5 was to improve performance with sparse arrays, provided order doesn't matter. For example, in the following:
var a = [0];
a[1000] = 1;
Iterating over a using for..in will be much faster than using a for loop, as it will only visit two properties whereas a for loop will try 1001.
However, this case is made redundant by ES5's forEach, which only visits members that exist, so:
a.forEach();
will also only iterate over two properties, in order.

What is the difference between 'for...in' and 'for each...in' in javascript? [duplicate]

This question already has answers here:
What is the difference between for..in and for each..in in javascript?
(4 answers)
Closed 8 years ago.
I know in C# you use foreach like this: foreach string str in array1 {console.writeline(str);}
Is "for each ... in" used like that in JavaScript too?
Afaik only Firefox supportes for each...in. It is not part of any standard and most tools like JSLint will throw errors if they encountered it.
The difference is that for...in loops over the keys of an object whereas for each...in loops over the values.
So the recommended way is to not use for each and do
for (var key in obj) {
console.log(obj[key]);
}
instead.
Update: I cannot say how it relates to C#. But regarding arrays: Never use for...in to traverse arrays (yellow box here):
Although it may be tempting to use this as a way to iterate over an Array, this is a bad idea. The for...in statement iterates over user-defined properties in addition to the array elements, so if you modify the array's non-integer or non-positive properties (e.g. by adding a "foo" property to it or even by adding a method or property to Array.prototype), the for...in statement will return the name of your user-defined properties in addition to the numeric indexes.
Use a normal for loop instead:
for(var i = 0, l = arr.length; i<l; i++)
or more fancy:
for(var i = arr.length; i--;)
There is no for each in in standard JavaScript. It may exist in specific implementations, if they want to extend the language.
for..in in JavaScript only relates to arrays by association, because it relates to objects, and arrays are objects. for..in does not loop through array entries, as for each does in C#. Nor does it loop through array indexes although people tend to think it does. (It loops through property names; array indexes are property names, but an array object can have other properties as well.) It's more like for each with the keys of a dictionary. I've discussed this fairly thoroughly in this article.
"for each ... in" returns the values rather than the keys... See here:
http://www.dustindiaz.com/for-each-in/
The in operator is used to enumerate the properties (the names, not the values) of a javascript object - and in javascript, all non-primitives are objects (inherit from Object).
You use it like this
var obj = {
a: "aaa",
b: "bbb"
};
for (var key in obj) {
if (obj.hasOwnProperty(key)){
console.log("obj has a property " + key + ", with a value of " + obj[key]);
}
}
Since in also enumerates properties inherited through the prototype chain, we must use hasOwnProperty to check if these are indeed the objects own properties, and not just inherited ones.
Note that the in operator should never be used to enumerate the items stored in arrays - for this you should use a regular for/while loop using the index.

How do I create a dynamic key to be added to a JavaScript object variable [duplicate]

This question already has answers here:
Add a property to a JavaScript object using a variable as the name? [duplicate]
(14 answers)
Closed 8 years ago.
I'm trying something like this, but this example does not work.
jsObj = {};
for (var i = 1; i <= 10; i++) {
jsObj{'key' + i} = 'example ' + 1;
}
What can I do to make a dynamic key like this?
Square brackets:
jsObj['key' + i] = 'example' + 1;
In JavaScript, all arrays are objects, but not all objects are arrays. The primary difference (and one that's pretty hard to mimic with straight JavaScript and plain objects) is that array instances maintain the length property so that it reflects one plus the numeric value of the property whose name is numeric and whose value, when converted to a number, is the largest of all such properties. That sounds really weird, but it just means that given an array instance, the properties with names like "0", "5", "207", and so on, are all treated specially in that their existence determines the value of length. And, on top of that, the value of length can be set to remove such properties. Setting the length of an array to 0 effectively removes all properties whose names look like whole numbers.
OK, so that's what makes an array special. All of that, however, has nothing at all to do with how the JavaScript [ ] operator works. That operator is an object property access mechanism which works on any object. It's important to note in that regard that numeric array property names are not special as far as simple property access goes. They're just strings that happen to look like numbers, but JavaScript object property names can be any sort of string you like.
Thus, the way the [ ] operator works in a for loop iterating through an array:
for (var i = 0; i < myArray.length; ++i) {
var value = myArray[i]; // property access
// ...
}
is really no different from the way [ ] works when accessing a property whose name is some computed string:
var value = jsObj["key" + i];
The [ ] operator there is doing precisely the same thing in both instances. The fact that in one case the object involved happens to be an array is unimportant, in other words.
When setting property values using [ ], the story is the same except for the special behavior around maintaining the length property. If you set a property with a numeric key on an array instance:
myArray[200] = 5;
then (assuming that "200" is the biggest numeric property name) the length property will be updated to 201 as a side-effect of the property assignment. If the same thing is done to a plain object, however:
myObj[200] = 5;
there's no such side-effect. The property called "200" of both the array and the object will be set to the value 5 in otherwise the exact same way.
One might think that because that length behavior is kind-of handy, you might as well make all objects instances of the Array constructor instead of plain objects. There's nothing directly wrong about that (though it can be confusing, especially for people familiar with some other languages, for some properties to be included in the length but not others). However, if you're working with JSON serialization (a fairly common thing), understand that array instances are serialized to JSON in a way that only involves the numerically-named properties. Other properties added to the array will never appear in the serialized JSON form. So for example:
var obj = [];
obj[0] = "hello world";
obj["something"] = 5000;
var objJSON = JSON.stringify(obj);
the value of "objJSON" will be a string containing just ["hello world"]; the "something" property will be lost.
ES2015:
If you're able to use ES6 JavaScript features, you can use Computed Property Names to handle this very easily:
var key = 'DYNAMIC_KEY',
obj = {
[key]: 'ES6!'
};
console.log(obj);
// > { 'DYNAMIC_KEY': 'ES6!' }
Associative Arrays in JavaScript don't really work the same as they do in other languages. for each statements are complicated (because they enumerate inherited prototype properties). You could declare properties on an object/associative array as Pointy mentioned, but really for this sort of thing you should use an array with the push method:
jsArr = [];
for (var i = 1; i <= 10; i++) {
jsArr.push('example ' + 1);
}
Just don't forget that indexed arrays are zero-based so the first element will be jsArr[0], not jsArr[1].

Categories