I have JSON,like,
var jsondata = {
"an_array" : [[2,4],[1,2]]
}
With JavaScript, I want to use a for loop to go through each element of the array in the array, like,
var grab_array = jsondata.an_array;
for (i = 0; i < grab_array.length; i++) {
grab_array[i][0]; //doing stuff
}
However, and I know this is probably some serious noob stuff, when I run typeof() on grab_array, it says it is an object and has a length of 0. What should I be doing?
I have JSON,like,
var jsondata = {
"an_array" : [[2,4],[1,2]]
}
With JavaScript, I want to use a for loop to go through each element of the array in the array, like,
var grab_array = jsondata.an_array;
for (i = 0; i < grab_array.length; i++) {
grab_array[i][0]; //doing stuff
}
However, and I know this is probably some serious noob stuff, when I run typeof() on grab_array, it says it is an object and has a length of 0. What should I be doing?
Share Improve this question edited Jan 7, 2011 at 6:24 Jacob Relkin 163k33 gold badges351 silver badges321 bronze badges asked Jan 7, 2011 at 6:11 JordanJordan 1833 silver badges7 bronze badges 1- Also, I retrieved the JSON using jQuery $.post(), from a PHP script that sets the header as application/json. I also set the "json" parameter for the $.post(), but tried removing it to test. – Jordan Commented Jan 7, 2011 at 6:13
4 Answers
Reset to default 3Well I can't follow the part with the length
being 0
, did you actually run the loop? It should work just fine.
But concerning the typeof
operator, that operator (together with instanceof operator) is probably the biggest design flaw of JavaScript. It is near of being pletely broken.
Although instanceof
still has its limited uses, typeof
really has only one
practical use case, which not happens to be checking the type of an object.
The JavaScript Typetable
Value Class Type
-------------------------------------
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
In the above table Type refers to the value the typeof
operator returns. As
you can see this is anything but consistent.
The Class refers to the value of the internal [[Class]]
property of an object.
From the Specification: Class can be one of the following values:
"Arguments"
,"Array"
,"Boolean"
,"Date"
,"Error"
,"Function"
,"JSON"
,"Math"
,"Number"
,"Object"
,"RegExp"
,"String"
In order to retrieve the value of Class one can has to make use of the
toString
method of Object
.
Checking the Class of an Object
function is(type, obj) {
return Object.prototype.toString.call(obj).slice(8, -1) === type;
}
is('String', 'test'); // true
is('String', new String('test')); // true
In the above code Object.prototype.toString
gets called with
this
being set to the object which its
Class value should be retrieved.
Checking whether a variable has been defined
typeof foo !== 'undefined'
The above will check whether foo
was actually declared or not, since just
referencing it would result in a ReferenceError
. This is the only thing
typeof
is actually useful for.
To Sum it up
Don't use typeof
unless you're checking for the existence of a variable.
Well, as for me, I could easily run this code
var jsondata = {
"an_array" : [[2,4],[1,2]]
}
var grab_array = jsondata.an_array,
max = grab_array.length;
for (i = 0; i < max; i++) {
console.log(grab_array[i][0]);
}
and the output was pretty expected: 2, 1 (each on new line). Concerning the second part of the question, you can easily test whether grab_array is an Array or not using following snippet:
if (grab_array.constructor == Array){
//do stuff
}
Also in ECMAScript5, you can use has Array.isArray() function, but since you can encounter the case when the destination environment does not support ECMAScript5, you may want to add this universal function for testing if the Object is an Array:
if (typeof Array.isArray === "undefined") {
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
}
and then simply do:
if (Array.isArray()){
//do stuff
}
Just use grab_array.constructor == Array
instead of typeof grab_array
when checking the type.
I'm not sure what is going on here to be honest. Throwing your code as is through the jQuery JSON parser leads me to a result where an_array.length
is 2. typeof still lists it as an object, but it has a length, and your loop should go through it. More code would probably be helpful.
As a debugging tip, trying doing a console.log call in Chrome or Firefox with Firebug of jsondata and see what es out. Make sure that the JSON object is ing back correct. However, that said, you can also use jQuery utilities to go through each element instead of a for loop. Try using jQuery.each() on it.