-1

I want to add attribute to a JS object, but in a custom place, After a given attribute.

var me = {
    name: "myname",
    age: "myage",
    bday: "mybday"
};
me["newAt"] = "kkk"; //this adds at the end of the object

Is there a way to specify the object (me), an attribute(age) in it and add a new attribute(newAt) right after the specified one? A better way than doing string operations?

var newMe = {
    name: "myname",
    age: "myage",
    newAt: "newAttr",
    bday: "mybday"
}

UPDATE: (Since people are more focused on why I'm asking this than actually answering it) I'm working on a drawable component based on user input - which is a JS object. And it has the ability to edit it - so when the user adds a new property based on "add new node" on the clicked node, and I was thinking of adding the new node right after it. And I want to update the data accordingly.

S.Dan
  • 1,733
  • 3
  • 21
  • 43

3 Answers3

3

JavaScript object is an unordered list of properties. The order is not defined and may vary when using with an iterator like for in. You shouldn't base your code on the order of properties you see in debugger or console.

Max Koretskyi
  • 85,840
  • 48
  • 270
  • 414
  • 1
    *"JavaScript object is an unordered list of properties."* This is no longer true as of ES2015. But you still shouldn't rely on order, even though ordre is now there. – T.J. Crowder Nov 01 '16 at 07:39
  • @T.J.Crowder, thanks, glad I answered, otherwise I wouldn't found that out :). Do you have any link at hand where I can read about that? – Max Koretskyi Nov 01 '16 at 07:44
  • [This answer](http://stackoverflow.com/a/32149345/157247) covers it. There's a better one somewhere that I haven't found yet. – T.J. Crowder Nov 01 '16 at 07:45
  • Thanks, if you find it, please drop it here) – Max Koretskyi Nov 01 '16 at 07:51
  • Here it is: http://stackoverflow.com/questions/30076219/does-es6-introduce-a-well-defined-order-of-enumeration-for-object-properties – T.J. Crowder Nov 01 '16 at 07:52
  • @T.J.Crowder I wouldn't say that particular statement is untrue. It's true that when the keys are enumerated it is done in a well-defined order, but the object itself is still unordered. – Paul Nov 01 '16 at 07:54
  • @SachiDangalla, what can I add to my answer to make it acceptable? – Max Koretskyi Nov 03 '16 at 07:40
3

JavaScript objects do, as of ES2015, have an order to their properties, although that order is only guaranteed to be used by certain operations (Object.getOwnPropertyNames, Reflect.ownKeys, etc.), notably not for-in or Object.keys for legacy reasons. See this answer for details.

But you should not rely on that order, there's no point to it, it's more complicated than it seems initially, and it's very hard to manipulate (you basically have to create a new object to set the order of its properties). If you want order, use an array.

Re your edit:

I'm working on a drawable component based on user input - which is a JS object. And it has the ability to edit it - so when the user adds a new property based on "add new node" on the clicked node, and I was thinking of adding the new node right after it. And I want to update the data accordingly.

The best way to do that is, if you want a specific order, keep the order of keys in an array and use that to show the object.

While you could use ES2015's property order for it, to do so you'd have to:

  • Require your users use a truly ES2015-compliant browser, because this cannot be shimmed/polyfilled
  • Destroy the object and recreate it adding the properties in the specific order you want each time you add a property
  • Forbid properties that match the specification's definition of an array index

It's just much more work and much more fragile than keeping the order in an array.

Community
  • 1
  • 1
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
0

The simplest solution I could find was to iterate through the keys of the parent and keep pushing them to form a clone of the parent. But to additionally push the new object if the triggered key is met.

var myObj = {
  child1: "data1",
  child2: "data2",
  child3: "data3",
  child4: "data4"
};

var a = (function addAfterChild(data, trigChild, newAttribute, newValue) {
  var newObj = {};
  Object.keys(data).some(function(k) {
    newObj[k] = data[k];
    if (k === trigChild) {
      newObj[newAttribute] = newValue;
    }
  });
  return newObj;
})(myObj, "child3", "CHILD", "VALUE");

document.getElementById("result").innerHTML = JSON.stringify(a);
<p id="result"></p>
S.Dan
  • 1,733
  • 3
  • 21
  • 43