#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);
}
…может быть изменен. Вы можете выполнить задание прямо в переменной части.
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i ] in foo) {}
Конечно, такое поведение отличается от того, что Object.keys()
происходит на самом деле (jsFiddle). Вы можете просто использовать прокладку в документации MDN.
Комментарии:
1. Мне это понравилось
var keys = [], i = 0; for (keys[i ] in foo) {}
12. Я слышал, что «для входа» не гарантирует порядок, вы не знаете, гарантирует ли 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
Тем не менее, Расширение встроенных объектов является спорным.