If I create a JavaScript object like:
var lst = [];
var row = [];
row.Col1 = 'val1';
row.Col2 = 'val2';
lst.push(row);
And then convert it to a string:
JSON.stringify(lst);
The result is an object containing an empty object:
[[]]
I would expect it to serialize like:
[[Col1 : 'val1', Col2: 'val2']]
Why do the inner objects properties not serialize?
Code snippet at JSFiddle.
If I create a JavaScript object like:
var lst = [];
var row = [];
row.Col1 = 'val1';
row.Col2 = 'val2';
lst.push(row);
And then convert it to a string:
JSON.stringify(lst);
The result is an object containing an empty object:
[[]]
I would expect it to serialize like:
[[Col1 : 'val1', Col2: 'val2']]
Why do the inner objects properties not serialize?
Code snippet at JSFiddle.
Share Improve this question asked Feb 20, 2012 at 17:31 AndomarAndomar 239k53 gold badges387 silver badges411 bronze badges 1- Visit json. You'll see that JSON has 2 structures. One allows key/value pairs, the other is a simple ordered list. JavaScript objects serialize to key/value pairs, and JavaScript arrays serialize to the ordered list. – user1106925 Commented Feb 20, 2012 at 17:36
4 Answers
Reset to default 4Because row
is an array, not an object. Change it to:
var row = {};
This creates an object literal. Your code will then result in an array of objects (containing a single object):
[{"Col1":"val1","Col2":"val2"}]
Update
To see what really happens, you can look at json2.js on GitHub. This is a (heavily reduced) snippet from the str
function (called by JSON.stringify
):
if (Object.prototype.toString.apply(value) === '[object Array]') {
//...
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
//...
}
//...
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
//...
}
//...
}
//...
Notice that arrays are iterated over with a normal for
loop, which only enumerates the array elements. Objects are iterated with a for...in
loop, with a hasOwnProperty
test to make sure the proeprty actually belongs to this object.
You use your inner array like an object, so make it an object instead of an array.
var lst = [];
var row = {};
row.Col1 = 'val1';
row.Col2 = 'val2';
lst.push(row);
or use it as an array
var lst = [];
var row = {};
row.push( 'val1' );
row.push( 'val2' );
lst.push(row);
You want row to be a dictionary, not a vector. Define it like this:
var row = {};
Since an array is a datatype in JSON, actual instances of Array
are stringified differently than other object types.
If a JavaScript Array
instance got stringified with its non-numeric keys intact, it couldn't be represented by the [ ... ]
JSON array syntax.
For instance, [ "Col1": "val1"]
would be invalid, because JSON arrays can't have explicit keys.
{"Col1": "val1"}
would be valid - but it's not an array.
And you certainly can't mix'n'match and get { "Col1": "val1", 1, 2, 3 ]
or something.
By the way, this works fine:
var lst = [];
var row = {};
row.Col1 = 'val1';
row.Col2 = 'val2';
lst.push(row);
alert(JSON.stringify(lst));