54

I have

var obj = {'b': 2, 'c': 3};

And i would like to add a property at the beginning (not at the end) of that object:

var obj = {'a': 1, 'b': 2, 'c': 3};

Is there a clean way to do that?

cedivad
  • 2,544
  • 6
  • 32
  • 41

8 Answers8

84

You can also use Object.assign() in ES6 (ES2015+).

let obj = {'b': 2, 'c': 3};
const returnedTarget = Object.assign({a: 1}, obj);

// Object {a: 1, b: 2, c: 3}
itsazzad
  • 6,868
  • 7
  • 69
  • 89
Justin
  • 4,203
  • 7
  • 41
  • 58
  • 6
    this method not change the original object, need supply new object then – Mada Aryakusumah Apr 25 '18 at 08:55
  • Correct @MadaAryakusumah, this returns a new object with the property added to the beginning. – Justin May 08 '18 at 03:47
  • 4
    This only works if the keys are of type string. If keys are of type Number and you are trying to add a string key then it will always add at the end i.e. obj = {"1" : "test1","2" : "test2"} and Object.assign({"key1": "value1"}, obj) will return {"1" : "test1","2" : "test2","key1": "value1"} it will not put that new key at the beginning. – Manjunath M Jul 25 '19 at 10:28
44

These days you could use the cool spread operator (...) in ES6 (ES2015+), try out the following:

const obj = {'b': 2, 'c': 3};
   
const startAdded = {'a':1 , ...obj};
console.log(startAdded);

const endAdded = {...obj, 'd':4};
console.log(endAdded);

Might help someone out there in the wild :)

darmis
  • 2,879
  • 1
  • 19
  • 21
20

The simplest way is to use the spread operator.

let obj = {'b': 2, 'c': 3};
let newObj = {'a': 1, ...obj};
Rohit Kawade
  • 239
  • 2
  • 5
12

JavaScript objects are unordered. There is no beginning or end. If you want order, use an array.

var arr = [
    { key: 'b', value: 2 },
    { key: 'c', value: 3 }
];

You can then add to the front of it with unshift:

arr.unshift({ key: 'a', value: 1 });
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • I need to access to obj['c'] using c as key of the array. As far as i know js arrays don't allow you to set arbitrary keys, this is why i'm stuck. – cedivad Oct 18 '13 at 19:14
  • 1
    You'd probably be best off maintaining an object and array, both containing the same objects. One keeping them in an order and one indexing them by letter. – Quentin Oct 18 '13 at 19:18
5

This Can be done using the lodash merge function like so:

var myObj = _.merge({ col1: 'col 1', col2: 'col 2'}, { col3: 'col 3', col4: 'col 4' });

Your final object will look like this:

{ col1: 'col 1', col2: 'col 2', col3: 'col 3', col4: 'col 4' }

As others mentioned, there is no guarantee that the order of the keys in the object will remain the same, depending on what you do with it. But, if you perform the merge as your final step, you should be ok. Note, the 'merge' function will produce a completely new object, it will not alter either of the objects you pass into it.

bbeny
  • 632
  • 1
  • 7
  • 18
3
var obj = {'b': 2, 'c': 3};
obj = Object.assign({a: 1}, obj);
console.log(obj); // {a: 1, b: 2, c: 3}

Hope this helps

Rami Mohamed
  • 2,505
  • 3
  • 25
  • 33
3

Javascript may not specify an order for properties in the language itself, but at least in my project (and perhaps yours), it certainly acts as if it does (JSON.stringify, debug watch windows, etc). I've never seen the for...in order be anything other than the order in which the properties were originally added. So for all intents and purposes in my project, and perhaps yours, this is very predictable.

And although this doesn't affect execution, this is a pain if you want to see a uniform list when properties of different items may be added in different order depending on how the object was created. Execution might not be the only thing that matters in project development. The ability to quickly visually inspect your objects also might matter.

Method 1 (high tech)

If you have spread, I would use that if you don't mind another object. But if you don't have spread (like in the older google apps script), or you need to keep the original object, you can do this:

objects.js

// Insert Property
Object.defineProperty(
  Object.prototype, 
  'insertProperty', 
  {
  value: function(name, value, index){
    // backup my properties
    var backup = {};
    // delete all properties after index
    var propertyIndex = 0;
    for(var propertyName in this) {
      if(this.hasOwnProperty(propertyName) && propertyIndex++ >= index) {
        backup[propertyName] = this[propertyName];  
        delete this[propertyName];
      }
    }
    this[name] = value;
    // restore all properties after index
    for(var propertyName in backup) {
      if(backup.hasOwnProperty(propertyName))
        this[propertyName] = backup[propertyName];  
    }
    return this; // same object; not a new object
  },
  enumerable: false,
});

usage

  var obj = {'b': 2, 'c': 3};
  obj.insertProperty('a',1,0); // {a:1, b:2, c:3}

notes

  • You can use any index to put the property wherever you want it. 0 puts it at the front.
  • You can certainly pull the function out and add an obj parameter if you don't like adding methods to the object prototype. In my project, adding methods to the prototype helps me; it doesn't hurt me.

Method 2 (low tech)

In some cases, you might be able to just create your object with all the properties you know it may eventually have in the order you want to see them appear, and later, instead of inserting the property, just set the property.

// creation
var a = {Id: null, foo: 'bar'}; 

// update later
if(!a.Id)
  a.Id = '123'; 
Community
  • 1
  • 1
toddmo
  • 20,682
  • 14
  • 97
  • 107
  • +1 for the low-tech method, which is certainly an out-of-the-box solution but allows for in-place modification of the target object. To be used IMO when the prop to be added is mandatory (props like ids are perfect candidates) – Renaud Pawlak Jun 01 '22 at 04:32
1

What worked for me is to use a temporary object for storing items in the desired order. For example:

var new_object = {}; 
new_object[name] = value; // The property we need at the start 

for (var key in old_object) { // Looping through all values of the old object 
  new_object[key] = old_object[key];
  delete old_object[key]; 
} 

old_object = new_object; // Replacing the old object with the desired one
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
VangelisB
  • 438
  • 5
  • 10