Доступ к нечисловым свойствам объекта по индексу?

88

Если у меня есть такой массив:

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

Я могу получить доступ к разным частям, выполнив следующие действия:

console.log(arr[1]);

Как я могу получить доступ к свойствам объекта по их порядку, а не по ключу?

Пример:

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

Как мне получить первое свойство для каждого объекта - «что-то» objи «даже больше» - jboбез явного использования имени свойства?

Некоторые из вас, кажется, думают, что я ищу что-то вроде:

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

Это не так, я специально хочу настроить таргетинг на индекс, как и в первом примере, если это возможно.

Дэрил
источник
2
Что вы имеете в виду под «массивом объектов»? Массив - это объект. Вы имеете в виду просто объект, который не является массивом, или вы имеете в виду массив объектов. И как jQuery влияет на ваш вопрос? Ваш единственный пример кода иллюстрирует ту часть, которую вы уже умеете делать. Как насчет того, чтобы дать какой-нибудь код, иллюстрирующий проблему .
user113716
@ Ӫ _._ Ӫ Причина, по которой я пометил jQuery, заключается в том, чтобы привлечь более широкую аудиторию. Я подумал, что любой, кто знает jQuery, должен иметь представление о массивах, чтобы не противоречить моему вопросу, это учебники.
Дэрил
4
На самом деле я бы сказал, что людей, «знающих» jQuery и не знающих JavaScript, больше, чем наоборот (по крайней мере, люди, знающие JavaScript, должны легко понимать jQuery) .... и что касается вашего фактического вопроса: нет, вы не может получить доступ к свойствам объекта по индексу. Они не заказываются.
Феликс Клинг,
2
«... Я полагал, что любой, кто знает jQuery, должен иметь представление о массивах ...» Я бы не стал на это ставить.
user113716
1
@Brogrammer: этот вопрос не имеет ничего общего с jQuery, поэтому тег jQuery неуместен.
outis

Ответы:

125

«Я специально хочу настроить таргетинг на индекс, как и в первом примере - если это возможно».

Нет, это невозможно.

Самое близкое, что вы можете получить, - это получить массив ключей объекта и использовать его:

var keys = Object.keys( obj );

... но нет гарантии, что ключи будут возвращены в указанном вами порядке. Так что это может выглядеть так:

keys[ 0 ];  // 'evenmore'
keys[ 1 ];  // 'something'
user113716
источник
6
Object.keys()можно было бы надежно использовать, если бы вы знали содержимое объекта. Подробнее здесь: stackoverflow.com/questions/280713/…
cronoklee
3
Метод Object.keys () возвращает массив перечисляемых свойств данного объекта в том же порядке, что и в цикле for ... in (разница в том, что цикл for-in перечисляет свойства в цепочке прототипов как Что ж). developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Амр Рагэй
6
все возможно
Кас Блум
48

Единственный способ, которым я могу это сделать, - это создать метод, который дает вам свойство using Object.keys();.

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

Демо: http://jsfiddle.net/UmkVn/

Можно было бы распространить это на все используемые объекты, Object.prototype;но обычно это не рекомендуется.

Вместо этого используйте вспомогательную функцию:

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
0x499602D2
источник
1
Это круто и работает как шарм! Почему это не принятый ответ? Вероятно, вам следует использовать, return this[Object.keys(this)[n]];чтобы сделать его универсальным.
cronoklee
3
Привет из 2016, мы, будущие люди, все еще думаем, что это должен быть принятый ответ. Отличное решение
mhodges
Причина, по которой это не принятый ответ, заключается в том, что до es6 порядок Object.keys не гарантируется. Таким образом, хотя этот код работает в нескольких JS-движках, не гарантируется, что он будет работать во всех из них. stackoverflow.com/questions/5525795/…
ptoinson
13

Вы можете использовать этот Object.values()метод, если не хотите использовать Object.keys().

В отличие от Object.keys()метода, который возвращает массив перечисляемых свойств данного объекта, например:

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

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

Распечатал бы следующий массив:

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

Object.values()Метод возвращает массив собственного перечислимого имущества данного объекта в values.

Итак, если у вас есть тот же объект, но вместо этого используйте значения,

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

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

Вы получите следующий массив:

[ 'somestring', 42, false ]

Итак, если вы хотите получить доступ object1.b, но вместо этого используя индекс, вы можете использовать:

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

Вы можете узнать больше об этом методе здесь .

Артур Сенна
источник
1
Этот способ из предложенных в этой теме кажется самым коротким и элегантным.
Петро Франко
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)

Редактировать:

«Я специально хочу настроить таргетинг на индекс, как и в первом примере - если это возможно».

На самом деле «индекс» - это ключ. Если вы хотите сохранить положение ключа, вам необходимо создать специальный объект для обработки этого.

Cuzzea
источник
Я знаю, что вы можете получить к нему доступ с помощью ключа, я не об этом спрашивал.
Дэрил
@Brogrammer: ваш вопрос неоднозначен, поэтому этот пост потенциально отвечает на вопрос в том виде, в котором он написан.
outis
2

с помощью jquery вы можете сделать это:

var arr = $.map(obj,function(value, key) {
    return value;
});
alert(obj[0]);
Мейсам Хошбахт
источник
2

Получите массив ключей, переверните его, затем запустите цикл

  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
  }
Карим
источник
1

вы можете создать массив, заполненный полями вашего объекта, и использовать индекс в массиве и получить доступ к свойствам объекта с помощью этого

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

this.myObject[this.propertiesName[0]]
Арфа
источник
1

Я пошел дальше и сделал для вас функцию:

 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"

StackGeek
источник
1
Не могли бы вы объяснить, что делается в вашем подходе?
Рахул Бхобе,
Я добавил в код несколько комментариев, чтобы вы могли понять, что делается.
StackGeek
0

Если вы не уверены, что Object.keys () вернет вам ключи в правильном порядке, вы можете попробовать эту логику.

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]])
Тьяго Лодди
источник