109

If I have an array like this:

var arr = ['one','two','three'];

I can access different parts by doing this:

console.log(arr[1]);

How can I access object properties by their order rather than by key?

Example:

var obj = {
    'something' : 'awesome',
    'evenmore'  : 'crazy'
},
jbo = {
    'evenmore'  : 'crazy',
    'something' : 'awesome'
};

How would I get the first property for each object–"something" from obj and "evenmore" from jbo–without explicitly using the property name?

Now, a few of you seem to think I'm after something like:

console.log(obj['something']);

This is not the case, I'm specifically looking to target the index, just like the first example - if it's possible.

outis
  • 75,655
  • 22
  • 151
  • 221
daryl
  • 14,307
  • 21
  • 67
  • 92
  • 2
    What do you mean by "Object array". An array *is* an object. Do you mean just an object that is not an array, or do you mean an array of objects. And how does jQuery factor in to your question? Your only code example illustrates the part that you already know how to do. How about giving some code that illustrates the *problem*. – user113716 Oct 23 '11 at 13:05
  • @Ӫ_._Ӫ The reason I tagged jQuery is to get a broader audience, I figured anyone who knows jQuery must have an understanding of array's, not to contradict my question, it's textbook stuff. – daryl Oct 23 '11 at 13:10
  • 4
    Actually I'd say there are more people "knowing" jQuery and not knowing JavaScript than vice versa (at least people who know JavaScript should be able to understand jQuery easily).... and with respect to your actual question: No, you cannot access objec properties by index. They are not ordered. – Felix Kling Oct 23 '11 at 13:13
  • 2
    *"...I figured anyone who knows jQuery must have an understanding of array's..."* I wouldn't bet on it. – user113716 Oct 23 '11 at 13:13
  • 1
    @Brogrammer: this question has nothing to do with jQuery, so the jQuery tag is inappropriate. – outis Oct 23 '11 at 13:19
  • Object array ... I guess you mean a hash-list, generally speaking. Do I assume correctly that you want to get the values? `values = function(o){var a=[];for(i in o) a.push(o[i]); return a; }` – Lorenz Lo Sauer Oct 23 '11 at 13:32
  • The answer to your question is that an object doesn't have numerical indexes. An array is a special kind of object where the keys are numerical indexes, but POJOs do not have numerical indexes, period. Can you extend the object like some of the answers below to fake it? Yes. But the answer to the question you asked is no, you can't, because object properties don't have a numerical index and can't be assumed to be in any sort of order. – jdforsythe Mar 19 '16 at 13:26
  • See http://stackoverflow.com/a/5525820/2990349 – jdforsythe Mar 19 '16 at 13:34

12 Answers12

143

"I'm specifically looking to target the index, just like the first example - if it's possible."

No, it isn't possible.

The closest you can get is to get an Array of the object's keys, and use that:

var keys = Object.keys( obj );

...but there's no guarantee that the keys will be returned in the order you defined. So it could end up looking like:

keys[ 0 ];  // 'evenmore'
keys[ 1 ];  // 'something'
user113716
  • 318,772
  • 63
  • 451
  • 440
  • 7
    `Object.keys()` could be used reliably if you know the object's contents. More detail here: http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop – cronoklee Jun 15 '12 at 17:20
  • 5
    The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well). https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys – Amr Ragaey May 28 '17 at 09:40
  • 10
    everything is possible – Cas Bloem Sep 12 '18 at 00:33
  • 1
    Well said, @CasBloem and, yes this is **possible**, using getters. We can access the properties just like array indices by defining getters for each property. See my answer. – Bikram Kumar Mar 19 '22 at 02:14
53

The only way I can think of doing this is by creating a method that gives you the property using Object.keys();.

var obj = {
    dog: "woof",
    cat: "meow",
    key: function(n) {
        return this[Object.keys(this)[n]];
    }
};
obj.key(1); // "meow"

Demo: http://jsfiddle.net/UmkVn/

It would be possible to extend this to all objects using Object.prototype; but that isn't usually recommended.

Instead, use a function helper:

var object = {
  key: function(n) {
    return this[ Object.keys(this)[n] ];
  }
};

function key(obj, idx) {
  return object.key.call(obj, idx);
}

key({ a: 6 }, 0); // 6
David G
  • 94,763
  • 41
  • 167
  • 253
  • 2
    This is cool & works like a charm! Why is it not the accepted answer? You should probably use `return this[Object.keys(this)[n]];` to make it generic. – cronoklee Jun 15 '12 at 17:10
  • 5
    Hello from 2016, we future folk still think this should be the accepted answer. Great solution – mhodges Feb 12 '16 at 21:34
  • The reason it is not the accepted answer is because until es6, the order of Object.keys is not guaranteed. So, even though that code works in a few JS engines, it is not guaranteed to work in all of them. https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – ptoinson Dec 21 '17 at 17:10
19

You can use the Object.values() method if you dont want to use the Object.keys().

As opposed to the Object.keys() method that returns an array of a given object's own enumerable properties, so for instance:

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.keys(object1));

Would print out the following array:

[ 'a', 'b', 'c' ]

The Object.values() method returns an array of a given object's own enumerable property values.

So if you have the same object but use values instead,

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.values(object1));

You would get the following array:

[ 'somestring', 42, false ]

So if you wanted to access the object1.b, but using an index instead you could use:

Object.values(object1)[1] === 42

You can read more about this method here.

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
Arthur Senna
  • 331
  • 3
  • 5
5
var obj = {
    'key1':'value',
    '2':'value',
    'key 1':'value'
}

console.log(obj.key1)
console.log(obj['key1'])
console.log(obj['2'])
console.log(obj['key 1'])

// will not work
console.log(obj.2)

Edit:

"I'm specifically looking to target the index, just like the first example - if it's possible."

Actually the 'index' is the key. If you want to store the position of a key you need to create a custom object to handle this.

Alberto Bonsanto
  • 17,556
  • 10
  • 64
  • 93
cuzzea
  • 1,515
  • 11
  • 22
  • I do know that you can access it by the key, that's not what I was asking. – daryl Oct 23 '11 at 13:07
  • @Brogrammer: your question is ambiguous, so this post does potentially answer the question as written. – outis Oct 23 '11 at 13:10
3

Yes, it is possible. We can define getters for each index, and return the property value, in the constructor method of the class. See this code.

class className {
  constructor() {
    this.name = "Bikram";
    this.age = 8;
    this.x = 89;
    this.y = true;


//Use a for loop and define the getters (with the object property's index as its "name") for each property using Object.defineProperty()

    for (let i = 0; i < Object.keys(this).length; i++) {

      Object.defineProperty(this, i, {
        get: function() {
          return Object.values(this)[i]}
      });
    }

  }
}


var b = new className();
console.log(b[0]); // same as b.name ("Bikram")
console.log(b[1]); // = b.age (8)
console.log(b[2]); // = b.x (89)
console.log(b[3]); // = b.y (true)

Edit: If you want to change the properties by their indices, which, of course, you do. Then, just define a corresponding setter for each property in the Object.defineProperty() method. It will look like:

// Insert this in place of the old one 

     Object.defineProperty(this, i, {
       get: function() {
          return Object.values(this)[i];
        },
        set: function(newValue) {
          this[Object.keys(this)[i]] = newValue;
        }
     })

     console.log(b[0]); // "Bikram"

     b[0] = "Bikram Kumar";

     console.log(b[0]); // "Bikram Kumar"

And now you have an "array-like-object" whose properties can be accessed or modified either by property key or its index :D

A side note: Notice that Object.keys() and Object.values() only return the enumerable properties. If you just declare a property and not assign it to any value, the Object.[key/value]s() methods will leave that in the returned array, because by default they are not enumerable. This might become confusing for the indices so defined (except the case the undeclared property is the last one).

To get around this, there is a simple way, if you want some property to have a index, but don't wanna assign it now. Just set it to undefined, and it will now be enumerable, and the indices won't be affected.

Bikram Kumar
  • 393
  • 1
  • 4
  • 15
2

by jquery you can do this:

var arr = $.map(obj,function(value, key) {
    return value;
});
alert(obj[0]);
2

Get the array of keys, reverse it, then run your loop

  var keys = Object.keys( obj ).reverse();
  for(var i = 0; i < keys.length; i++){
    var key = keys[i];
    var value = obj[key];
    //do stuff backwards
  }
Kareem
  • 5,068
  • 44
  • 38
1

you can create an array that filled with your object fields and use an index on the array and access object properties via that

propertiesName:['pr1','pr2','pr3']

this.myObject[this.propertiesName[0]]
arfa
  • 99
  • 1
  • 2
  • 3
1

I went ahead and made a function for you:

 Object.prototype.getValueByIndex = function (index) {
     /*
         Object.getOwnPropertyNames() takes in a parameter of the object, 
         and returns an array of all the properties.
         In this case it would return: ["something","evenmore"].
         So, this[Object.getOwnPropertyNames(this)[index]]; is really just the same thing as:
         this[propertyName]
    */
    return this[Object.getOwnPropertyNames(this)[index]];
};

let obj = {
    'something' : 'awesome',
    'evenmore'  : 'crazy'
};

console.log(obj.getValueByIndex(0)); // Expected output: "awesome"
Rahul Bhobe
  • 4,165
  • 4
  • 17
  • 32
1

Sure it is possible, but it is not as immediate as accessing to an array by its indexes, but still possible and even relatively simple actually: in fact you don't have to struggle too much. This code sample will show how:

var obj = {
    'alfa'  : 'value of obj the key alfa',
    'beta'  : 'value of obj the key beta',
    'gamma'  : 'value of obj the key gamma'
};

var jbo = {
    'alfa'  : 'value of jbo the key alfa',
    'beta'  : 'value of jbo the key beta',
    'gamma'  : 'value of jbo the key gamma'
};

alert  ( obj[Object.keys(obj)[1]] );
alert ( jbo[Object.keys(jbo)[1]] );

/* you can even put it into a for loop as follows */

for (i=0;i<3;i++)
{
    document.writeln ( "<br>This could be even a piece of HTML: " + obj[Object.keys(obj)[i]] );
    document.writeln ( "<br>This could be even a piece of HTML: " + jbo[Object.keys(jbo)[i]] );
}

Explication:

As you know the Object.keys() statement returns an array of all enumerable properties (which means all keys) of the object you type into its round parenthesis. So the only thing you need is to indicate the index after that array, which will returns the key literal found at that index. The key itself is "digested" as usual by the object which returns the value at that key.

willy wonka
  • 1,440
  • 1
  • 18
  • 31
0

If you are not sure Object.keys() is going to return you the keys in the right order, you can try this logic instead

var keys = []
var obj = {
    'key1' : 'value1',
    'key2' : 'value2',
    'key3' : 'value3',
}
for (var key in obj){
    keys.push(key)
}
console.log(obj[keys[1]])
console.log(obj[keys[2]])
console.log(obj[keys[3]])
Thiago Loddi
  • 2,212
  • 4
  • 21
  • 35
0

You can also construct a function that will return the value of a property by accepting two parameters: the object and the "index" (order position)

function getValue(obj, index) {
   let keysArray = Object.keys(obj)
   let key = keysArray[index]
   return obj[key]
}

Usage example getValue(obj, 2)

Snippet

let obj = {a: 'dog', b: 'cat', c: 'mouse'}

function getValue(obj, index){
  let keysArray = Object.keys(obj)
  let key = keysArray[index]
  return obj[key]
}

console.log(getValue(obj, 2))
Gass
  • 7,536
  • 3
  • 37
  • 41