Если есть объект Javascript:
var objects={...};
Предположим, что он имеет более 50 свойств, не зная имена свойств (которые не знают "ключи" ), как получить каждое значение свойства в цикле?
Если есть объект Javascript:
var objects={...};
Предположим, что он имеет более 50 свойств, не зная имена свойств (которые не знают "ключи" ), как получить каждое значение свойства в цикле?
Используя простой цикл for..in
:
for(var key in objects) {
var value = objects[key];
}
В зависимости от того, какие браузеры вам необходимо поддерживать, это можно сделать несколькими способами. Подавляющее большинство браузеров в дикой среде поддерживают 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
нельзя использовать для создания частных свойств). Новый API Reflect
от 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' });
Если вы хотите избежать shimming, когда существует нативный Object.values
, вы можете сделать:
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
Помните о браузерах/версиях, которые вам необходимо поддерживать. Вышеприведенные правила верны там, где реализованы методы или языковые функции. Например, поддержка ECMAScript 2015 была отключена по умолчанию в V8 до недавнего времени, в которой использовались браузеры, такие как Chrome. Следует избегать использования ECMAScript 2015 до тех пор, пока браузеры, которые вы намереваетесь поддерживать, не реализуют функции, которые вам нужны. Если вы используете babel для компиляции вашего кода в ECMAScript 5, тогда у вас есть доступ ко всем функциям в этом ответе.
Здесь используется функция многократного использования для получения значений в массиве. Он также учитывает прототипы.
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
Если у вас есть доступ к 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. На каждой итерации k устанавливается клавиша o.
Вы можете прокручивать клавиши:
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
ES5 Object.keys
var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
Для тех, кто рано адаптируется к эпохе CofeeScript, здесь есть еще один эквивалент.
val for key,val of objects
Это может быть лучше, потому что objects
можно уменьшить, чтобы снова набираться и уменьшать читаемость.
objects[key] for key of objects
используйте polyfill как:
if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}
затем используйте
Object.values(my_object)
3) прибыль!
По-видимому, как я недавно узнал, это самый быстрый способ сделать это:
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]];
}
Вы можете использовать этот компонент объект-значения, который я написал, чтобы получить все значения объекта.
Примеры:
values({ a: 1, b: 2, c: 3 }) // => [1, 2, 3]
Вот как это работает:
function values(object: {[any]: any}): any[] {
const objValues = [];
forEach(object, val => objValues.push(val));
return objValues;
};
Этот микрокомпьютер MPM также может сделать трюк.
Здесь функция, аналогичная 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));
Я понимаю, что немного опаздываю, но здесь прокладка для нового метода firefox 47 Object.values
Object.prototype.values = Object.prototype.values || function(obj) {
return this.keys(obj).map(function(key){
return obj[key];
});
};
Гораздо лучший подход заключается в том, что вы прикрепляете некоторую функцию к прототипу объекта, чтобы вы могли получать свойства каждого объекта, на который вы вызываете свойства().
Object.prototype.properties=function(){
var result=[];
for(var property in this){
if (this.hasOwnProperty(property)){
result.push(property);
}
return result;
}
Так как 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']
var objects={...}; this.getAllvalues = function () {
var vls = [];
for (var key in objects) {
vls.push(objects[key]);
}
return vls;
}
в ECMAScript5 используйте
keys = Object.keys(object);
В противном случае, если браузер не поддерживает его, используйте известный for..in loop
for (key in object) {
// your code here
}
Теперь я использую 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']
использовать
console.log(variable)
и если вы используете консоль google chrome open с помощью Ctrl + Shift + j
Перейти к → Консоль