it-swarm.com.ru

Как получить все значения свойств объекта Javascript (не зная ключей)?

Если есть объект Javascript:

var objects={...};

Предположим, у него более 50 свойств, не зная имен свойств (это не зная "ключей"), как получить каждое значение свойства в цикле?

425
Mellon

Используя простой цикл for..in:

for(var key in objects) {
    var value = objects[key];
}
416
Tatu Ulmanen

В зависимости от того, какие браузеры вы должны поддерживать, это можно сделать несколькими способами. Подавляющее большинство браузеров в дикой природе поддерживают ECMAScript 5 (ES5), но имейте в виду, что во многих приведенных ниже примерах используется Object.keys, который недоступен в IE <9. См. таблица совместимости) .

ECMAScript 3+

Если вам нужно поддерживать более старые версии 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+

Вы можете использовать эти методы в любом браузере, который поддерживает 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+ (A.K.A. ES6)

Массивы проще итерировать с 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 2017+

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 shim

Наконец, как отмечено в комментариях и 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, то у вас есть доступ ко всем функциям этого ответа.

964
qubyte

Вот функция многократного использования для получения значений в массив. Он также принимает во внимание прототипы.

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.Push(obj[key]);
        }
    }
    return vals;
}
30
teh_senaus

Если у вас есть доступ к Underscore.js, вы можете использовать функцию _.values следующим образом:

_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
28
jichi

Если вам действительно нужен массив значений, я нахожу это чище, чем создание массива с циклом 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.

14
zzz

ES5 Object.keys

var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
8
MrBii

Вы можете пройтись по клавишам:

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
5
ariera

использовать полифилл как:

if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}

затем используйте

Object.values(my_object)

3) прибыль!

3
user40521

Для тех, кто рано адаптировался к эпохе CofeeScript, вот еще один аналог.

val for key,val of objects

Что может быть лучше, чем это, потому что objects может быть уменьшено для повторного ввода и уменьшена читаемость.

objects[key] for key of objects
3
Ch.Idea

Очевидно - как я недавно узнал - это самый быстрый способ сделать это:

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]];
}
2
dylnmc

ECMA2017 года:

Object.values(obj) выберет все значения свойств в виде массива.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

2
ishandutta2007

Используйте: Object.values(), мы передаем объект в качестве аргумента и получаем массив значений в качестве возвращаемого значения.

Это возвращает массив данного объекта с собственными перечисляемыми значениями свойств. Вы получите те же значения, что и при использовании цикла for in, но без свойств в Prototype. Этот пример, вероятно, прояснит ситуацию:

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
1
Willem van der Veen

Я понимаю, что немного опоздал, но вот shim для нового метода firefox 47 Object.values

Object.prototype.values = Object.prototype.values || function(obj) {
  return this.keys(obj).map(function(key){
    return obj[key];
  });
};
0
Jamie

Object.entries делают это лучше.

  var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
 
   Object.entries(dataObject).map(itemArray => { 
     console.log("key=", itemArray[0], "value=", itemArray[1])
  })
0
Asif J

Вот функция, похожая на 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));
0
jaggedsoft

Совместим с ES7 даже некоторые браузеры пока не поддерживают его

Поскольку 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']

Как только браузеры станут совместимыми с ES7, вам не придется ничего менять в своем коде.

0
Abdennour TOUMI