通过索引访问非数值对象属性? ?

如果我有一个这样的数组:

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

我可以通过这个来访问不同的部分:

console.log(arr[1]);

如何通过对象属性的顺序而不是键来访问它们?

例如:

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

如何在不显式使用属性名的情况下获得每个对象的第一个属性—— obj中的“ something”和 jbo中的“ even more”?

现在,你们中的一些人似乎认为我在追求类似于:

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

事实并非如此,我专门寻找目标索引,就像第一个例子-如果可能的话。

136664 次浏览
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.

"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'

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

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]])

by jquery you can do this:

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

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.

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
}

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]]

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"

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.

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.

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))