0

I'm trying to stringify an object but don't know why it is not working as expected:

function request(url) {
  this.url = url;
  this.head = [];
}

var r = new request("http://test.com");
r.head["cookie"] = "version=1; skin=new";
r.head["agent"] = "Browser 1.0";
document.write(JSON.stringify(r));

I hope this object can be stringified as:

{"url":"http://test.com","head":["cookie":"version=1; skin=new", "agent":"Browser 1.0"]}

But I only get:

{"url":"http://test.com","head":[]}

How to fix it?

Deqing
  • 14,098
  • 15
  • 84
  • 131
  • possible duplicate of [JavaScript associative array to JSON](http://stackoverflow.com/questions/4425289/javascript-associative-array-to-json) – Felix Kling Aug 16 '13 at 07:11

2 Answers2

1

You want the hear property of r to be an associative array I think (like in PHP). They don't exist in JavaScript. Array's have values that are indexed by a number.

Since r.head is an object (array is object in JS) you can add properties to it with r.head["whatever property name"]="value" but these properties don't seem to be serialized to JSON when you use JSON.stringify because r.head is defined as an array and it'll only serialize the numbered index values.

To fix this you can define r.head as an object so JSON.stringify will serialize all properties.

function request(url) {
  this.url = url;
  this.head = {};
}

var r = new request("http://test.com");
r.head["cookie"] = "version=1; skin=new";
r.head["agent"] = "Browser 1.0";
document.write(JSON.stringify(r));

If you run the following code in your cosole (press F12 in your browser) you'd see that arrays are not serialized in the same way as objects are:

var b = [];
b.something=22
console.log(b.something);
console.log(JSON.stringify(b));//=[]
console.log(b.hasOwnProperty("something"))//=true


b = {};
b.something=22
console.log(b.something);
console.log(JSON.stringify(b));//={"something":22}
console.log(b.hasOwnProperty("something"))//=true
HMR
  • 37,593
  • 24
  • 91
  • 160
1

It would be impossible to serialize it the way you are hoping to.

With this object:

function request(url) {
  this.url = url;
  this.head = []; 
}

This variation:

var r = new request("http://test.com");
r.head.push({"cookie": "version=1; skin=new"});
r.head.push({"agent": "Browser 1.0"});

document.write(JSON.stringify(r));

would give you:

{"url":"http://test.com","head":[{"cookie":"version=1; skin=new"},{"agent":"Browser 1.0"}]}

If you were to change the object to:

function request(url) {
  this.url = url;
  this.head = {}; 
}

var r = new request("http://test.com");
r.head["cookie"] = "version=1; skin=new";
r.head["agent"] = "Browser 1.0";

document.write(JSON.stringify(r));

would give you:

{"url":"http://test.com","head":{"cookie":"version=1; skin=new","agent":"Browser 1.0"}}

The first variation is guaranteed to give you the head values in order when you iterate it. It also has the advantage in that you can later insert things in specific order if that is of interest.

The second version, by convention, will give you the items back in the order they were inserted as long as there are no number based keys, but that ordering is not guaranteed by the ecma spec.

6502
  • 112,025
  • 15
  • 165
  • 265
dc5
  • 12,341
  • 2
  • 35
  • 47