This question already has answers here:
Javascript Object returns junk values
(2 answers)
Closed 8 years ago.
In the below JavaScript code :-
var a = [];
for (i in a) {
alert(i);
}
I am getting o/p as - $family, $constuctor, each, clone, clean, invoke, associate, link, contains, append, getlast, getRandom, include, combine, erase, empty, flatten, pick, hexToRgb, rgbToHex.
Can anybody explain why is that so?Has it got to do something with properties of Array objects and if so then why aren't all the properties alerted? Also , if we take a empty object literal like var a = {} , we don't get any o/p.
Now , if I change the above code like :-
var a = [9,2];
for (i in a) {
if (a.hasOwnProperty(i)) {
alert(a.hasOwnProperty(i));
alert(i);
}
}
I get the output as 0 and 1.Why is that so ? Are those the properties of this Array object (which are also the indexes) ?
The for-in syntax is for objects. It iterates all fields of the object, including methods. When you want to iterate an array, always use this:
for (var i = 0; i < array.size; i++) {
doSomething(array[i]);
}
Your latter loop with hasOwnProperty doesn't iterate over the standard methods of arrays, because your array a inherited these methods from the base Array class, so they aren't it's own properties. But when you explicitely add a method to an array, it should also list the function because it is now an own property:
var a = [9,2];
a.hello = function() { };
for (i in a) {
if (a.hasOwnProperty(i)) {
alert(a.hasOwnProperty(i));
alert(i);
}
}
This should list 0, 1 and hello.
In case you expected it to output 9 and 2 and you wonder why it outputs 0 and 1: That's because the for-in array iterates over the keys, not over the values. And arrays are basically objects where each array element is a property with the array index as a name. So
var a = [9, 2];
is equivalent to this object (plus the stuff inherited from Array):
var a = {
0: 9,
1: 2
}
Related
Is there any kind of built-in method that would iterate through the object parameters without loop. Like the array object has methods(forEach, sort, filter..).
For example there's an array
var numbers = [3,342,23,22,124];
var max = 0;
for(var i=0;i<numbers.length;i++){
if(numbers[i] > max){
max = numbers[i];
}
}
alert(max);
Instead of looping sort() method could be used
var numbers = [3,342,23,22,124];
numbers.sort(function(a,b){return b - a});
alert(numbers[0]);
Is there any method for regular objects {} in JavaScript, that would work the same way as sort()?
More generally is there any way to avoid such looping:
for(var parameter in object){
var data = object[parameter]
exampleMethod(data);
}
is there a way to execute a function several times without looping?
No, but you can often use a function like Object.keys() to open a pathway to the Array prototype methods like .forEach().
The Object.keys() method returns an array with the "own" property names of an object. (The "own" names are the names of properties directly on the object, and not inherited from the prototype chain.) From there, you can use the Array methods like .forEach to iterate through the property names and, by using those to reference the object, through the property values as well.
For example, consider this object:
var dimensions = {
length: 20,
height: 30,
width: 40
};
If you wanted to sum up the edges, you could do this:
var perimeter = Object.keys(dimensions).reduce(function(sum, dkey) {
sum += 4 * dimensions[dkey];
return sum;
}, 0);
Note also the related methods Object.getOwnPropertyNames() and Object.getOwnPropertySymbols(), which expand the properties available for iteration.
Not like sort because there is no order of properties in JavaScript objects. However, you can use Object.keys and map to turn an object into an array of values.
var o = {a:1,b:3, c, :2};
var arr = Object.keys(o).map(key=>o[key]).sort((a,b)=>b-a);
var max = arr[0];
For regular iteration, combine keys and forEach
Object.keys(o).forEach(key=>console.log('key',key, 'value', o[key]));
This question already has answers here:
How do I enumerate the properties of a JavaScript object? [duplicate]
(14 answers)
Closed 8 years ago.
In Javascript, I'd like to have an object with three properties, "zone1", "zone2", "zone3", each of which store an array of place names. I would like to search for a match by iterating through the arrays to find a place name.
The following questions almost gets me there, but don't work for me because I am not using jQuery, and I want the value, not the key:
Performing a foreach over an associative array of associative arrays
Getting a list of associative array keys
My code looks like this:
var zoneArray = {};
zoneArray["zone1"] = ["placeA", "placeB"];
zoneArray["zone2"] = ["placeC", "placeD"];
function getZone(place, zoneArray) {
var zone;
for (var key in zoneArray) {
for(i = 0; i<key.length; i++) {
if(key[i] == place) {
zone = key;
return zone;
}
}
}
}
getZone("placeC", climateZoneArray);
Apparently however, "key[i]" is referring to letters of the zone names, like, "z" "o" "n" "e"
Could anybody please help me understand or best handle this situation in Javascript?
Use zoneArray[key] to access the array.
for (var key in zoneArray) {
var arr = zoneArray[key]
for(i = 0; i<arr.length; i++) {
if(arr[i] == place) {
zone = key;
return zone;
}
}
}
Using for ... in to iterate over an object's properties can lead to some pretty surprising results, especially if you're working in an environment where Object.prototype has been extended. This is because for ... in will iterate over an objects enumerable properties and the enumerable properties contained in that objects prototype chain. If this isn't what you want but you are going to use for ... in anyways, it's recommended to have a conditional statement at the top of the loop that checks that the property belongs to the object which is being iterated over. (if (!foo.hasOwnProperty(x)) continue;). Luckily, there is Object.keys(). You can use Object.keys() to get an array of an objects own enumerable properties, if you do this you can skip hasOwnProperty ugliness. Instead of iterating over the object you can iterate over an array of it's keys.
var collection = {
zone1: ['placeA', 'placeB'],
zone2: ['placeC', 'placeD']
};
function getZone(needle, collection) {
var zones = Object.keys(collection),
found;
for (var i = 0, l = zones.length; i < l; i++) {
found = collection[zones[i]].filter(function(place) {
return needle == place;
});
if (found.length > 0) {
return zones[i];
}
}
};
console.log(getZone('placeC', collection));
This is also here on jsfiddle.net
One last thing, be very careful when creating variables, in the inner for loop you created the variable i without using the var keyword. This resulted in i being bound to the global context, something you really want to avoid.
I have placed my frustrations into a jsfiddle to observe here: http://jsfiddle.net/8ShFr/1/
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
alert('why does this array have a length of ' + brand_new_array.length + '???');
I am doing some calculations client side that require me to set javascript array keys of 1M+ in number.
Not knowing exactly what that number is demands that I iterate through the first 1M+ empty array values before getting to an array key that holds data.
I simply want to set a single large key value for a javascript array without creating a bunch of empty keys before it?
I am using jQuery.each to iterate over the array, and it keeps going through array[0], array[1], array[2], etc... when I only set array[123125] for example.
Just filter out the undefineds.
brand_new_array = brand_new_array.filter(function(n){return n !== undefined});
The reason for the length being 10 is that an array's length is set to the largest index number in the array. However, this does not mean there are 9 other values in there because in javascript an array is at its base an object.
The length is just a property in the object. Arrays in javascript are at their core objects (Array Object 1). They merely act like arrays through an api.
"Whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index" 1
1. ECMAScript Language Specification 15.4 Array Objects
You probably want to just use an object with strings for keys (the keys can be the toString() of Numbers, which will happen automatically if you try to use numbers).
var sparse_array_obj = {};
sparse_array_obj[10003210234] = 4; // Fair dice roll
sparse_array_obj[5] = 17; // Truly random number
sparse_array_obj[900] = Math.random(); // Pseudorandom number
for(var i in sparse_array_obj)
console.log(sparse_array_obj[i]);
The downside is that Javascript provides no guarantees about the iteration order through an object (since its keys are unordered by definition). There are however ways around this, such as:
// Sort the keys in numeric order
var sorted_keys = Object.keys(sparse_array_obj).sort(function(a, b){ return a - b; });
for(var i = 0; i < sorted_keys.length; i++)
console.log(sparse_array_obj[sorted_keys[i]]);
Object.keys needs to be shimmed in older browsers.
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
var result = brand_new_array.filter(function(e) { return e != undefined;})[0];
alert(brand_new_array.indexOf(result));
Travis J is right. The array in your example only contains one entry, but your use of jQuery.each() is making you think there are 10 entries because it iterates from 0 up to the highest index number of the array (defines the length). This is from the jQuery.each() API documentation.
A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.
Going back to your example:
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
This will result in only one console.log output:
for(var i in brand_new_array)
console.log(brand_new_array[i]);
This will result in 10 console.log outputs:
$(brand_new_array).each( function(i,e) { console.log(e) })
Similarly, this will result in 10 console.log outputs:
for (var i=0;i<brand_new_array.length;i++)
console.log(brand_new_array[i]);
If you really want to stick with using .each() then you can skip the undefined indices like so:
$(brand_new_array).each( function(i,e) {
if (this.hasOwnProperty(i)){ console.log(e) }
})
Filter the falsy items - including undifined:
var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
var b=a.filter(Boolean); // [1,2,"b",{},3,5]
The length is 11 because the index starts at 0.
x[0] = undefined
x[1] = undefined
x[2] = undefined
x[3] = undefined
x[4] = undefined
x[5] = undefined
x[6] = undefined
x[7] = undefined
x[8] = undefined
x[9] = undefined
x[10] = "random array value"
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between an array and an object?
The item exists in the array but it says that the array is 0 length?
I m a bit confused in object and associative array in javascript. I read this :question but this question says that there is not much of a difference in both. I wrote this in the console:
var a = [];
a["A"] = 1;
var b = {};
b["B"] = 2;
var c = new Object();
c["C"] = 3;
output for above are as:
a gives {A : 1}
b gives {B : 2}
c gives {C : 3}
All above three cases gives same reault as in they all gives an object. Question is how all above 3 cases are treated in javascript.
An array is also an object, that's why you can use non-numeric indices also. Those will be added as properties to the array object, not part of the array data.
The difference between an array and an object, is that the array counts properties with a numeric index as being part of the array data, and updates the length property accordingly. (Also the Array object has some specific methods to work with the array data.)
var a = [];
a[42] = 1337;
Now the length has changed to include the item:
alert(a.length); // shows 43
Using strings or numbers as index doesn't matter, a numeric index counts even if it's a string:
alert(a[42]); // shows 1337
alert(a["42"]); // shows 1337
Reducing the length removes the properties outside it:
a.length = 10;
alert(a[42]); // shows undefined
In your example, b and c are essentially the same thing, because {} is the equivalent of new Object().
Coming back to a, it's defined as an Array which is a special kind of Object in the sense that numeric properties (based on uint32) are treated differently. Its length property gets updated when those properties are added and removed.
When you use 'A' as an index, it gets treated as a regular property, defined by how Object works with properties, so you can access it as a.A or a['A'] whereas an index of [5] can only be accessed using a[5].
Normally, the debug output of an array is always [] unless the length property is non-zero, so the output you've shown is somewhat irregular.
Trivia
According to the ECMAScript documentation, a particular value p can only be an array index if and only if:
(p >>> 0 === p) && (p >>> 0 !== Math.pow(2, 32) - 1)
See also:
The item exists in the array but it says that the array is 0 length?
Let's start by clarifying something:
new Object() is the same as {}
new Array() is the same as []
The latter are just shortened forms of the former.
Behind the scenes, everything in javascript is basically an object (this is an exaggeration but fairly accurate). Arrays are simply derived from objects. Here's a fairly rudimentary example of what an Array REALLY looks like:
var myArray = {};
myArray[0] = 'value1';
myArray[1] = 'value2';
myArray[2] = 'value3';
myArray[length] = 3;
The prototype of an array contains all the methods. For example:
// myArray#push
myArray.prototype.push = function(val){
myArray[this.length] = val;
this.length++;
}
Another way to illustrate this is to take an array and add keys that are not numeric:
var example = [];
example.push(0);
example.push(1);
example.push(2);
example['a'] = 'a';
example['b'] = 'b';
example['c'] = 'c';
example.log = function(){
for(var i = 0, l = this.length; i < l; i++){
console.log( example[i] );
}
console.log(this['a']);
console.log(this['b']);
console.log(this['c']);
}
// example[0] is 0
// example[1] is 1
// example[2] is 2
// example.log is my custom function
example.log(); // results in
// 0
// 1
// 2
// a
// b
// c
Also, don't always believe everything the console tells you. For example, if you do this:
var console_confusion = {};
console_confusion.length = 100;
console_confusion.splice = function(){ /* do absolutely nothing */ };
console.log( console_confusion );//results in
//
// in Chrome:
// [undefined × 100]
//
Chrome will interprut anything with a numeric length property and a splice function as an Array. This is why jQuery objects look like Arrays in the console.
Please read the following article – http://www.2ality.com/2012/12/arrays.html
In short, “regular arrays”, denoted as [] in JavaScript, are also objects, just like {}, but they have length property and “numeric” keys (“indicies”), plus their internal __proto__ property points at Array.prototype object, which holds all Array methods, such as push or forEach etc.
first is an array
second is an object array
third is an array object
This is a method I tried to run:
function SayHello() {
cars = new Array();
cars[0] = "Toyota";
cars[1] = "Mitsubishi";
cars[2] = "Honda";
for (car in cars) {
alert(car);
}
}
This returned:
0
1
2
When I changed the code to this:
function SayHello() {
cars = new Array();
cars[0] = "Toyota";
cars[1] = "Mitsubishi";
cars[2] = "Honda";
for (car in cars) {
alert(cars[car]);
}
}
It returned the names correctly.
My question is, does the for-in loop just return an index in an orderly fashion? Thanks.
Yes, the value of the iterator is the name of the property. It's highly frowned upon to use it to loop over arrays, however. For example, consider this:
x = ['a', 'b', 'c'];
x.foo = 'bar';
for (i in x) alert(i); // 0, 1, 2, foo
It's intended for iterating over the members of an object:
x = { a : 'apple', b : 'banana', c : 'carrot' };
for (i in x) {
// and it's best to check that the property actually exists
// on this object, not just on one of its prototypal ancestors:
if (x.hasOwnProperty(i)) {
alert(i); // 'a', 'b', 'c'
}
}
More information about why on the YUI Blog
Yes, it will be the index within the collections.
See here:
var mycars = ["Saab", "Volvo", "BMW"];
for (var car in mycars)
{
document.write(mycars[car] + "<br />");
}
As you can see, the use of the variable as an index into the collection.
You can use for each ... in syntax (introduced in Javascript 1.6) that will iterate over values. See here.
for each...in - similar to for...in, but iterates over the values of object's properties, rather than the property names themselves. (New in JavaScript 1.6.)
As far as I know, Javascript 1.6+ is only used in Firefox at this time.
Yes and no. It returns indexes, not the values, and it returns them as quoted strings. "0", "1", etc..
The plus side of this is that for in works the same if you use a javascript object as associative array.
It returns the "key" of each item. Same result will be achieved with such "array":
cars = {0: "Toyota", 1: "Mitsubishi", 2: "Honda"};
use the regular for...
for (var i = 0; i < cars.length; i++) {
let car = cars[i];
// Do what you want from here
}
for...in - iterates over all enumerable properties of an object that are keyed by strings (for simple arrays it returns the element's index).
for...of - iterates over the property values but can only be used for iteratable types: built-in String, Array, array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables (not for generic objects).