Reputation: 13800
I'm trying to loop through an object like you would an array. I'm struggling to append the loop counter to the variable name.
I have an object like this (output with dump()
, which I found here):
object(2): {
elem0: array(4): {
[0]: string(27): "http://placehold.it/300x300"
[1]: string(3): "0.8"
[2]: string(4): "-150"
[3]: string(3): "200"
}
elem1: array(4): {
[0]: string(27): "http://placehold.it/300x300"
[1]: string(3): "0.6"
[2]: string(3): "-70"
[3]: string(3): "458"
}
}
Here's how I'm trying to loop through it:
jQuery(document).ready(function($) {
// Provides object-measuring functionality
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
// Returns the number of objects in my object
var size = Object.size(window.depthElems);
/*
This is where I'm having difficulty.
I would like to use window.depthElems.elem0,
then window.depthElems.elem1, etc.
*/
for (var i = 0; i < size; i++) {
$('.wrapper').append('<img src="' + window.depthElems.elem+i+[0] + '" />');
}
});
Upvotes: 0
Views: 427
Reputation: 1615
I will, for the sake of argument, also provide my question as answer. You can use:
for(element in window.depthElems) {
if(window.depthElems.hasOwnProperty(element)) {
$('.wrapper').append('<img src="' + window.depthElems[element] + '" />');
}
}
This is not only more elegant, but also requires far less code. Of course if there is a reason to use the other code, please say so.
Note: This code is edited to also include the ability to read 'arrays', however the question was to make it work with 'objects'. If you use 'objects' the 'hasOwnProperty' check is superfluous.
Note #2: You can also use var hasOwn = Object.prototype.hasOwnProperty;
like Azder said, which is a nice safeguard.
Upvotes: 3
Reputation: 4728
I apologize if my answer is over the top, I just like to prevent further hurt by miss-using JS (which I have experienced a lot) .
jQuery(document).ready(function($) {
var i; // there is no block scope in JS, so better to be clear and define i here
var $wrapper; // also
// Changing the JS built-in objects is problematic most of the time
// You should learn from jQuery and do wrapping instead
// Or at least just a good namespasing like:
// MyFramework.objectSize = function (obj) {}
Object.size = function(obj) {
var size = 0, key;
var hasOwn = Object.prototype.hasOwnProperty; // will explain further down
for (key in obj) {
// if obj has redifined hasOwnProperty = function(){ return false; }?
// it's better to use hasOwn like this if(hasOwn.call(obj,key)) {}
// and please do use braces even if only 1 statement
if(hasOwn.call(obj,key)) size++;
}
return size;
};
// Returns the number of objects in my JSON object
var size = Object.size(window.depthElems);
$wrapper = $('.wrapper'); // cached so jQuery doesn't search for it each iteration
// i is scoped to the whole function anyways
for (i = 0; i < size; i++) {
// $.each even guards you of the changing DOM which can cause
// infinite loops (you don't have that problem here, but... good to know
$.each(window['depthElems'+i],function(index,element){
$wrapper.append('<img src="' + element + '" />');
});
}
});
Also, since you already make objects named elem1, elem2, elem3,... you might as well use a two dimensional array, like window.depthElems = [[],[],[]]
Upvotes: 2