Якщо є об’єкт 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
шимНарешті, як зазначається в коментарях та тех_сенаусом в іншій відповіді, можливо, варто використати один із них як прокладку. Не хвилюйтесь, наступне не змінює прототип, воно просто додає метод 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]
Якщо ви дійсно хочете масив Значення, я вважаю це чистішим, ніж будувати масив з циклом для ... у циклі.
ECMA 5.1+
function values(o) { return Object.keys(o).map(function(k){return o[k]}) }
Варто зазначити, що в більшості випадків вам не потрібен масив значень, це буде швидше зробити:
for(var k in o) something(o[k]);
Це повторюється над клавішами Object o. У кожній ітерації k встановлюється ключ 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-of:
Використання:, 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, оскільки старші веб-переглядачі не підтримують 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']