Получить массив ключей объекта

#javascript #ecmascript-5

Вопрос:

Я хотел бы получить ключи объекта JavaScript в виде массива либо в jQuery, либо в чистом JavaScript.

Есть ли менее подробный способ, чем этот?

 var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}
 

Комментарии:

1. Помимо добавления if(foo.hasOwnProperty(key)) , это то, что я бы сделал. Или используйте $.map .

2. Хотя, о, для питонического однострочника…

3. старый вопрос, поэтому не стоит полного ответа, но для тех, кто хочет поиграть… jsfiddle.net/LR5D9/3 это решение решает проблему, связанную с тем, что объявления прототипов путают for var in x циклы

4. @несинхронизированные, пожалуйста, никогда не публикуйте решения в качестве комментариев. Ваш комментарий намеренно нарушает четкий и преднамеренный дизайн структуры страницы.

Ответ №1:

Воспользуйся Object.keys :

 var foo = {
  'alpha': 'puffin',
  'beta': 'beagle'
};

var keys = Object.keys(foo);
console.log(keys) // ['alpha', 'beta'] 
// (or maybe some other order, keys are unordered). 

Это функция ES5. Это означает, что он работает во всех современных браузерах, но не будет работать в устаревших браузерах.

В ES5-прокладке есть реализация Object.keys , которую вы можете украсть

Комментарии:

1. Примечание: Это работает только в современных браузерах (под этим я подразумеваю не IE

2. А как насчет мобильных браузеров ?

3. @SmartyTwiti: Я не уверен. Я бы предположил, что это так, как в Chrome или Firefox.

4. MDN также имеет вышеупомянутую полиполнку, но отмечает ошибки в IE7 и, возможно, 8, а затем ссылается на гораздо более короткую полиполнку здесь: tokenposts.blogspot.com.au/2012/04/…

5. сколько раз я пытался вызвать ключи как свойство экземпляра, прежде чем до меня дошло, что это метод статического класса… понимание api—

Ответ №2:

Вы можете использовать jQuery $.map .

 var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});
 

Комментарии:

1. Или each , если вы что-то делаете с ними. $.each(foo, function(index, value){/* do something with index */});

Ответ №3:

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

Однако ваш пример кода…

 var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}
 

jsFiddle.

…может быть изменен. Вы можете выполнить задание прямо в переменной части.

 var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i  ] in foo) {}
 

jsFiddle.

Конечно, такое поведение отличается от того, что Object.keys() происходит на самом деле (jsFiddle). Вы можете просто использовать прокладку в документации MDN.

Комментарии:

1. Мне это понравилось var keys = [], i = 0; for (keys[i ] in foo) {} 1

2. Я слышал, что «для входа» не гарантирует порядок, вы не знаете, гарантирует ли Object.keys?

3. @ChrisStephens Не гарантирует порядок, даже если ключи оказываются в упорядоченном массиве.

4. все эти решения hasOwnProperty() , конечно же, нуждаются в проверке?

5. @TIMINeutron Нет причин, по которым этого не должно быть 🙂

Ответ №4:

На случай, если вы здесь ищете что-то, чтобы перечислить ключи вложенного объекта n-глубины в виде плоского массива:

 const getObjectKeys = (obj, prefix = '') => {
  return Object.entries(obj).reduce((collector, [key, val]) => {
    const newKeys = [ ...collector, prefix ? `${prefix}.${key}` : key ]
    if (Object.prototype.toString.call(val) === '[object Object]') {
      const newPrefix = prefix ? `${prefix}.${key}` : key
      const otherKeys = getObjectKeys(val, newPrefix)
      return [ ...newKeys, ...otherKeys ]
    }
    return newKeys
  }, [])
}

console.log(getObjectKeys({a: 1, b: 2, c: { d: 3, e: { f: 4 }}})) 

Ответ №5:

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

 var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
 

Комментарии:

1. Может быть, так и должно быть var enumerableKeysOnThePrototypeChain 😉

2. Может быть, мы достаточно умны, чтобы знать, что нам не нужно беспокоиться о свойствах hasOwnProperty, если объект создан полностью в нашей компетенции, а не импортирован откуда-то еще

3. не такой питонический, как 2-й ответ @alex ( for (keys[i ] in foo) {} ), хотя, потому что вы все еще выполняете Array.push() (не говоря уже об объявлении целой функции). Реализация pythonic должна как можно больше полагаться на неявное понимание, а в противном случае использовать лямбда-выражение.

Ответ №6:

Краткие сведения

Для получения всех ключей объекта вы можете использовать Object.keys() . Object.keys() принимает объект в качестве аргумента и возвращает массив всех ключей.

Пример:

 const object = {
  a: 'string1',
  b: 42,
  c: 34
};

const keys = Object.keys(object)

console.log(keys);

console.log(keys.length) // we can easily access the total amount of properties the object has 

В приведенном выше примере мы храним массив ключей в keys const. Затем мы можем легко получить доступ к количеству свойств объекта, проверив длину массива ключей.

Получение значений с помощью: Object.values()

Дополнительная функция Object.keys() ис Object.values() . Эта функция принимает объект в качестве аргумента и возвращает массив значений. Например:

 const object = {
  a: 'random',
  b: 22,
  c: true
};


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

Ответ №7:

Если вы решите использовать Underscore.js тебе лучше это сделать

 var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
 

Комментарии:

1. Почему? Каково же объяснение?

Ответ №8:

2022 год, а в JavaScript все еще нет надежного способа работы с хэшами?

Это выдает предупреждение, но работает:

 Object.prototype.keys = function() { return Object.keys(this) }
console.log("Keys of an object: ", { a:1, b:2 }.keys() )

// Keys of an object:  Array [ "a", "b" ]
// WARN: Line 8:1:  Object prototype is read only, properties should not be added  no-extend-native
 

Тем не менее, Расширение встроенных объектов является спорным.