Отримайте масив ключів об'єкта


371

Я хотів би отримати ключі об’єкта JavaScript як масив, або в jQuery, або в чистому JavaScript.

Чи є менш дослівний спосіб, ніж цей?

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

4
Окрім того if(foo.hasOwnProperty(key)), щоб додати , це я би робив. Або використовувати $.map.
Ракета Hazmat

10
О, пітонічний однолінійний лайнер, хоча ...
Річард

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

Відповіді:


618

Використання 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-shim має реалізацію, Object.keysяку ви можете вкрасти


5
Примітка. Це працює лише в сучасних браузерах (маючи на увазі, не IE <9).
Ракета Хазмат

2
А як щодо мобільних браузерів?
Marwen Trabelsi

1
@SmartyTwiti: Я не впевнений. Я припускаю, що це так, як Chrome або Firefox.
Ракета Хазмат

У MDN також є зазначений вище Polyfill, але він відзначає помилки в IE7 та, можливо, 8, а потім посилається на набагато коротший Polyfill тут: tokenposts.blogspot.com.au/2012/04/…
Campbeln

То як же це зробити перед ES5?
Andrew S

59

Ви можете використовувати jQuery $.map.

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

Або eachякщо ви щось робите з ними. $.each(foo, function(index, value){/* do something with index */});
Кріс

33

Звичайно, 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 .


8
Мені сподобалось це var keys = [], i = 0; for (keys[i++] in foo) {}+1
Jashwant

Я чув, що "для в" не гарантує порядок, чи знаєте ви, чи робить Object.keys?
Кріс Стівенс

@ChrisStephens Жоден гарантійний порядок, навіть якщо ключі знаходяться в упорядкованому масиві.
алекс

2
всі ці рішення потребують hasOwnProperty()перевірки, напевно?
несинхронізований

1
@TIMINeutron Немає причини, чому це не повинно :)
alex

7

Я не знаю про менш багатослівний, але мене надихнули примусити наступне на одному рядку за запитом однолінійки, не знаю, наскільки це пітонічно;)

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

3
Можливо, так і має бути var enumerableKeysOnThePrototypeChain;)
alex

1
Можливо, ми досить розумні, щоб знати, що нам не потрібно турбуватися про hasOwnProperty, якщо об’єкт створений цілком під нашою компетенцією, на відміну від імпорту звідкись іншого
Dexygen

не такий пітонічний, як друга відповідь @ alex ( for (keys[i++] in foo) {}), тому що ви все ще виконуєте Array.push()(не кажучи вже про оголошення цілої функції). Пітонічна реалізація повинна якомога більше покладатися на неявне розуміння, а не дотримуючись цього, використовуючи лямбда-вираз.
коуберт

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


1

Підсумок

Щоб отримати всі ключі Об’єкта, який ви можете використовувати 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

У наведеному вище прикладі ми зберігаємо масив клавіш у клавішах const. Тоді ми можемо легко отримати доступ до кількості властивостей об’єкта, перевіривши довжину масиву ключів.

Отримання значень за допомогою: Object.values()

Додатковою функцією Object.keys()є Object.values(). Ця функція приймає об'єкт як аргумент і повертає масив значень. Наприклад:

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


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


1

Якщо ви вирішили використовувати Underscore.js, вам краще зробити

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.