11

I have a JSON object which is initiated when the page is loaded, like this:

data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;

Is there a way to inject an element before the first foo element, so that when doing a for var i in data, the new element will be looped through before the elements that were added when the object was initiated?

The reason is, I'm displaying some items to the user. When the user adds a new item via javascript, I want this new item to be displayed above all the existing items, however when I add the new item, i.e

data[newItem] = newItem;

Then the JSON object looks like this:

data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;
data[newItem] = newItem;

Instead of how I want, which is:

data[newItem] = newItem;
data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;

Any ideas?

Ali
  • 261,656
  • 265
  • 575
  • 769
  • [this topic](http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop) is probably relevant. Namely the part that says: If order is relevant, *use an array.* – J. Holmes May 27 '12 at 12:03

6 Answers6

17

In JS, object properties' order is not guaranteed. Therefore, even if they are ordered in the JSON string, when parsed as a JS object, you will never predict in what order they come up.

Better use arrays instead. You could use the unshift() method to put the item in the first index.

var data = [bar,bar2,bar3];

data.unshift(newItem);

//data = [newItem,bar,bar2,bar3];
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • 1
    See also http://stackoverflow.com/questions/648139/is-the-order-of-fields-in-a-javascript-object-predictable-when-looping-through-t and http://stackoverflow.com/questions/586182/javascript-insert-item-into-array-at-a-specific-index – georgebrock May 27 '12 at 12:06
  • Not an option, I've already coded it as an object. I'll have to change it in a gazillion places to use an array. What's a way to make it work as an object? – Ali May 27 '12 at 12:10
  • so there's no way to use `data["foo"]` to get the corresponding data..I'm wondering if there's libraries simulate Python's OrderedDict in JavaScript – wong2 May 27 '12 at 12:10
  • Besides, with an array, I'd have the same issue. Say an array is initalized with 5 elements, then the user adds a new one and I want to move it to the start of the array. How would I do that? – Ali May 27 '12 at 12:12
  • @ClickUpvote `Array.unshift()` see my answer. Arrays have [a host of manipulation methods](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array#Methods) you can use like `push` to add to the end, `pop` to remove the end, `shift` to remove the first etc. – Joseph May 27 '12 at 12:14
  • 1
    @Click Upvote You can use array like object. `var arr = []; arr.foo = 'bar';` the only thing is you will not be able to access that `foo` inside a `for(var i = 0; i < arr.length; i++){...}`. So, your existing code can be same. You can still access them inside `for(var key in data){...}` loop, even if you change your `data = []`. –  May 27 '12 at 12:19
  • Why would the property order not be guaranteed? Is this still the case in 2019? – Jon Jul 10 '19 at 16:23
9

As a compliment to Joseph the Dreamer's answer, I have ran some quick checks in firefox & chrome.

Firefox:

var obj = {};

obj.a = 'a';
obj.c = 'c';
obj.b = 'b';
obj['0'] = '0';

for(var i in obj){
    console.log(i);
}

//prints:
a
c
b
0

Chrome:

var obj = {};

obj.a = 'a';
obj.c = 'c';
obj.b = 'b';
obj['0'] = '0';

for(var i in obj){
    console.log(i);
}

//prints:
0
a
c
b
Community
  • 1
  • 1
5

I've stumbled upon this and achieved it using:

const newObject = Object.assign({first: value}, oldObject)

As mentioned, order is not guaranteed but for me this is good enough. :)

raubas
  • 674
  • 7
  • 6
3

Is there a way to inject an element before the first foo element?

Which comes first in the array:

window.object or window.alert?

Neither, objects don't have an order. If you want an array use an array. Objects are not arrays.

If you want

var ThingsInOrder = [
  FirstThing,
  SecondThing,
  ThirdThing
];
ThingsInOrder.push(ForthThing);

Use an array.

If you want:

var ThingsNeverInOrder = {
  Window,
  Alert,
  Derp,
  Herp
};

ThingsNeverInOrder.foo = bar;

Use an object.

Incognito
  • 20,537
  • 15
  • 80
  • 120
0

Instead of adding new value in the same object, you can create a new object and arrange properties order as you want. example :

var objj1 = {name:'viru',lastname:'nehra'};

So create a new object with new property which you want on top:

var obj2 = {age: 21}

and the run:

for(var key in objj1){
   obj2[key] = objj1[key]
}

obj2 = {age: 21, name: "viru", lastname: "nehra"}
wscourge
  • 10,657
  • 14
  • 59
  • 80
virender nehra
  • 470
  • 6
  • 12
-3

I think you can convert it to string, append your data at the beginning of the string then re-convert the string to json using "eval"

Samir Adel
  • 2,691
  • 2
  • 15
  • 16