Если есть объект Javascript:
var objects={...};
Предположим, у него более 50 свойств, не зная имен свойств (это не зная «ключей»), как получить каждое значение свойства в цикле?
Если есть объект Javascript:
var objects={...};
Предположим, у него более 50 свойств, не зная имен свойств (это не зная «ключей»), как получить каждое значение свойства в цикле?
Ответы:
Используя простой for..in
цикл:
for(var key in objects) {
var value = objects[key];
}
enumerable
флаг false. Это - среди прочего - означает, что вы не будете перебирать методы класса, но вы будете перебирать методы, созданные другими способами.
В зависимости от того, какие браузеры вы должны поддерживать, это можно сделать несколькими способами. Подавляющее большинство браузеров в дикой природе поддерживают ECMAScript 5 (ES5), но имейте в виду, что многие из приведенных ниже примеров используют Object.keys
, чего нет в IE <9. См. Таблицу совместимости .
Если вам нужно поддерживать более старые версии IE, то этот вариант для вас:
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var val = obj[key];
// use val
}
}
Вложенный if
гарантирует, что вы не перечислите свойства в цепочке прототипов объекта (это поведение, которое вы почти наверняка хотите). Вы должны использовать
Object.prototype.hasOwnProperty.call(obj, key) // ok
скорее, чем
obj.hasOwnProperty(key) // bad
потому что ECMAScript 5+ позволяет создавать объекты без прототипов Object.create(null)
, и у этих объектов не будет hasOwnProperty
метода. Непослушный код может также создавать объекты, которые переопределяют hasOwnProperty
метод.
Вы можете использовать эти методы в любом браузере, который поддерживает ECMAScript 5 и выше. Они получают значения из объекта и избегают перечисления по цепочке прототипов. Где obj
ваш объект:
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var val = obj[keys[i]];
// use val
}
Если вам нужно что-то более компактное или вы хотите быть осторожнее с функциями в циклах, тогда Array.prototype.forEach
ваш друг:
Object.keys(obj).forEach(function (key) {
var val = obj[key];
// use val
});
Следующий метод создает массив, содержащий значения объекта. Это удобно для зацикливания.
var vals = Object.keys(obj).map(function (key) {
return obj[key];
});
// use vals array
Если вы хотите сделать тех, кто использует, Object.keys
безопасным против null
(как for-in
есть), то вы можете сделать Object.keys(obj || {})...
.
Object.keys
возвращает перечислимые свойства. Для перебора простых объектов этого обычно достаточно. Если у вас есть что-то с не перечисляемыми свойствами, с которыми вам нужно работать, вы можете использовать Object.getOwnPropertyNames
вместо Object.keys
.
Массивы проще итерировать с ECMAScript 2015. Вы можете использовать это в своих интересах при работе со значениями одно за другим в цикле:
for (const key of Object.keys(obj)) {
const val = obj[key];
// use val
}
Используя функции жирной стрелки ECMAScript 2015, отображение объекта в массив значений становится однострочным:
const vals = Object.keys(obj).map(key => obj[key]);
// use vals array
ECMAScript 2015 представляет Symbol
, экземпляры которых могут использоваться в качестве имен свойств. Чтобы получить символы объекта для перечисления, используйте Object.getOwnPropertySymbols
(эта функция Symbol
не может использоваться для создания частных свойств). Предоставляется новый Reflect
API из ECMAScript 2015 Reflect.ownKeys
, который возвращает список имен свойств (включая не перечисляемые) и символов.
Массивы были удалены из ECMAScript 6 перед публикацией. До их удаления решение выглядело бы так:
const vals = [for (key of Object.keys(obj)) obj[key]];
// use vals array
ECMAScript 2016 добавляет функции, которые не влияют на эту тему. Спецификация ECMAScript 2017 добавляет Object.values
и Object.entries
. Оба возвращают массивы (что будет удивительно для некоторых по аналогии с Array.entries
). Object.values
можно использовать как есть или с for-of
циклом.
const values = Object.values(obj);
// use values array or:
for (const val of Object.values(obj)) {
// use val
}
Если вы хотите использовать и ключ, и значение, то Object.entries
это для вас. Это производит массив, заполненный [key, value]
парами. Вы можете использовать это как есть или (обратите внимание также на назначение деструктуризации ECMAScript 2015) в for-of
цикле:
for (const [key, val] of Object.entries(obj)) {
// use key and val
}
Object.values
шайбаНаконец, как отмечено в комментариях и teh_senaus в другом ответе, возможно, стоит использовать один из них в качестве прокладки. Не волнуйтесь, следующее не меняет прототип, оно просто добавляет метод Object
(который гораздо менее опасен). Используя функции жирных стрелок, это также можно сделать в одной строке:
Object.values = obj => Object.keys(obj).map(key => obj[key]);
который вы можете теперь использовать как
// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });
Если вы хотите избежать шимминга, когда Object.values
существует натив , то вы можете сделать:
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
Знайте о браузерах / версиях, которые вам нужно поддерживать. Вышесказанное является правильным, если реализованы методы или языковые функции. Например, до недавнего времени поддержка ECMAScript 2015 по умолчанию была отключена в V8, что обеспечивало работу таких браузеров, как Chrome. Следует избегать использования возможностей ECMAScript 2015 до тех пор, пока браузеры, которые вы намереваетесь поддерживать, не реализуют необходимые вам функции. Если вы используете babel для компиляции кода в ECMAScript 5, то у вас есть доступ ко всем функциям этого ответа.
obj
дважды. Я думаю, создание вспомогательной функции неизбежно? Что-то вроде значений (obj).
Object.values = obj => Object.keys(obj).map(key => obj[key]);
Вот функция многократного использования для получения значений в массив. Он также принимает во внимание прототипы.
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
Object
не является большой проблемой ( Object.keys
это обычная прокладка), вы, вероятно, думаете о модификации прототипа Object.
hasOwnProperty()
? Как бы ключ был перебран в цикле того объекта, который не имеет свойства?
Если у вас есть доступ к Underscore.js, вы можете использовать такую _.values
функцию:
_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
Если вам действительно нужен массив значений, я нахожу это чище, чем создание массива с циклом for ... in.
ECMA 5.1+
function values(o) { return Object.keys(o).map(function(k){return o[k]}) }
Стоит отметить, что в большинстве случаев вам не нужен массив значений, это будет быстрее:
for(var k in o) something(o[k]);
Это перебирает ключи Объекта o. В каждой итерации к задается ключ o.
ES5 Object.keys
var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
Вы можете пройтись по клавишам:
foo = {one:1, two:2, three:3};
for (key in foo){
console.log("foo["+ key +"]="+ foo[key]);
}
будет выводить:
foo[one]=1
foo[two]=2
foo[three]=3
ECMA2017 года:
Object.values(obj)
принесет вам все значения свойств в виде массива.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
Очевидно - как я недавно узнал - это самый быстрый способ сделать это:
var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
// do whatever in here
var obj = objs[objKeys[i]];
}
Вопрос не указывает, нужны ли также унаследованные и не перечисляемые свойства.
Существует вопрос получения всего, наследуемых и неперечислимых свойств , которые Google не может легко найти.
Мое решение для этого:
function getAllPropertyNames(obj) {
let result = new Set();
while (obj) {
Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
obj = Object.getPrototypeOf(obj);
}
return [...result];
}
И затем переберите их, просто используйте цикл for:
Используйте:, Object.values()
мы передаем объект в качестве аргумента и получаем массив значений в качестве возвращаемого значения.
Это возвращает массив данного объекта с собственными перечисляемыми значениями свойств. Вы получите те же значения, что и при использовании for in
цикла, но без свойств в прототипе. Этот пример, вероятно, прояснит ситуацию:
function person (name) {
this.name = name;
}
person.prototype.age = 5;
let dude = new person('dude');
for(let prop in dude) {
console.log(dude[prop]); // for in still shows age because this is on the prototype
} // we can use hasOwnProperty but this is not very elegant
// ES6 +
console.log(Object.values(dude));
// very concise and we don't show props on prototype
Вот функция, похожая на PHP array_values ()
function array_values(input) {
var output = [], key = '';
for ( key in input ) { output[output.length] = input[key]; }
return output;
}
Вот как получить значения объекта, если вы используете ES6 или выше:
Array.from(values(obj));
Так как, Object.values(<object>)
будет встроен в ES7 &
Пока вы не дождетесь поддержки всех браузеров, вы можете обернуть его внутри функции:
Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])
Затем :
Object.vals({lastname:'T',firstname:'A'})
// ['T','A']
Object.entries делают это лучше.
var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
Object.entries(dataObject).map(itemArray => {
console.log("key=", itemArray[0], "value=", itemArray[1])
})
const myObj = { a:1, b:2, c:3 }
Получить все значения:
кратчайший путь:
const myValues = Object.values(myObj)
const myValues = Object.keys(myObj).map(key => myObj[key])
в использовании ECMAScript5
keys = Object.keys(object);
В противном случае, если ваш браузер не поддерживает его, используйте хорошо известные for..in loop
for (key in object) {
// your code here
}
object[key]
для получения значений в цикле.
for..in
(и hasOwnProperty), чтобы он ничего не получил ... Я бы хотел, чтобы ECMAScript 5-й был определен Object.pairs
(и Object.items
для [[key, value], ..]
), но, увы, нет.
Сейчас я использую Dojo Toolkit, потому что старые браузеры не поддерживают Object.values
.
require(['dojox/lang/functional/object'], function(Object) {
var obj = { key1: '1', key2: '2', key3: '3' };
var values = Object.values(obj);
console.log(values);
});
Вывод :
['1', '2', '3']