Как выполнить цикл или перечислить объект JavaScript?

avatar
Tanmoy
26 марта 2009 в 06:01
2297246
44
3223

У меня есть объект JavaScript, подобный следующему:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Теперь я хочу перебрать все элементы p (p1, p2, p3 ...) и получить их ключи и значения. Как я могу это сделать?

При необходимости я могу изменить объект JavaScript. Моя конечная цель - перебрать несколько пар ключ-значение, и, если возможно, я хочу избежать использования eval.

Источник

Ответы (44)

avatar
levik
26 марта 2009 в 06:12
4789

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

Вот фрагмент:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

Альтернатива For-of с Object.keys ():

var p = {
    0: "value1",
    "b": "value2",
    key: "value3"
};

for (var key of Object.keys(p)) {
    console.log(key + " -> " + p[key])
}

Обратите внимание на использование for-of вместо for-in, если он не используется, он вернет undefined для названных свойств, а <for-in08><235593> использование только собственных свойств объекта без свойств всей цепочки прототипов

Использование нового метода Object.entries():

Примечание. Этот метод изначально не поддерживается Internet Explorer. Вы можете рассмотреть возможность использования Polyfill для старых браузеров.

const p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (let [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}
danieltalsky
27 января 2012 в 15:56
367

В javascript каждый объект имеет набор встроенных пар ключ-значение, которые содержат метаинформацию. Когда вы перебираете все пары ключ-значение для объекта, вы тоже перебираете их. hasOwnPropery () отфильтровывает их.

Ben Y
27 февраля 2014 в 16:08
66

Фактически, For ... в не является устаревшим. Для каждого ... в есть. Но мне очень нравится термин археологи ... Я собираюсь начать использовать его.

avatar
Sahil Thummar
12 марта 2022 в 04:23
0
  1. Использование for...in и Object hasOwnProperty

        var p = {
            "p1": "value1",
            "p2": "value2",
            "p3": "value3"
        };
    
        for (var key in p) {
            if (p.hasOwnProperty(key)) {
                console.log(key, ' : ', p[key]);
            }
        }
  2. Использование for...of и ключей объектов

        var p = {
          "p1": "value1",
          "p2": "value2",
          "p3": "value3"
        };
    
        for (var key of Object.keys(p)) {
          console.log(key, " : ", p[key])
        }
  3. Использование ключей объектов и forEach

        var p = {
            "p1": "value1",
            "p2": "value2",
            "p3": "value3"
        };
    
        Object.keys(p).forEach(function(key) {
            console.log(key, ' : ', p[key]);
        });
  4. Использование for...of и записей объектов

        var p = {
            "p1": "value1",
            "p2": "value2",
            "p3": "value3"
        };
    
        for (let [key, value] of Object.entries(p)) {
          console.log(key, ' : ', value);
        }
  5. Использование элементов объекта и forEach

        var p = {
            "p1": "value1",
            "p2": "value2",
            "p3": "value3"
        };
    
        Object.entries(p).forEach(([key, value]) => console.log(key, ' : ', value));
avatar
lodey
3 февраля 2022 в 15:10
2
Object.entries(myObject).map(([key, value]) => console.log(key, value))

Вы можете попробовать так. myObject будет {name: "", phone: ""} так и так, это сгенерирует ключ и значение. Итак, ключ здесь name, phone, а значение похоже на dog, 123123.

.

Пример {name: "dog"}

Здесь ключ name и значение dog.

Maximilian Peters
9 февраля 2022 в 07:50
0

Привет, добро пожаловать в Stackoverflow! Как объяснялось в туре, этот сайт является хранилищем полезных вопросов и ответов на них. Ваш ответ существенно не отличается от других ответов и не очень полезен, поскольку не добавляет никакой новой ценности или информации. Пожалуйста, избегайте дублирования ответов, либо отредактируйте свой ответ, чтобы повысить ценность, либо полностью удалите его, это гарантирует, что все вопросы и ответы на сайте останутся полезными, а не разрозненными/дублированными.

avatar
Akhil Ramani
28 августа 2021 в 12:51
8

Однострочный и более читаемый код может быть ..

Object.entries(myObject).map(([key, value]) => console.log(key, value))
avatar
Kamil Kiełczewski
6 марта 2020 в 17:36
28

Производительность

Сегодня 2020.03.06 я тестирую выбранные решения в Chrome v80.0, Safari v13.0.5 и Firefox 73.0.1 на MacOs High Sierra v10.13.6

Выводы

  • решения на основе for-in (A, B) являются быстрыми (или самыми быстрыми) для всех браузеров для больших и малых объектов
  • на удивление for-of (H) решение быстро работает с хромом для маленьких и больших объектов
  • решения, основанные на явном индексе i (J, K), довольно быстры во всех браузерах для небольших объектов (для firefox также быстро для больших объектов, но средне-быстро в других браузерах)
  • решения на основе итераторов (D, E) самые медленные и не рекомендуются
  • решение C медленное для больших объектов и средне-медленное для мелких

enter image description here

Подробности

Тесты производительности были выполнены для

  • небольшой объект - с 3 полями - вы можете выполнить тест на своем компьютере ЗДЕСЬ
  • «большой» объект - с 1000 полями - вы можете выполнить тест на своем компьютере ЗДЕСЬ

Ниже во фрагментах представлены использованные решения

function A(obj,s='') {
	for (let key in obj) if (obj.hasOwnProperty(key)) s+=key+'->'+obj[key] + ' ';
  return s;
}

function B(obj,s='') {
	for (let key in obj) s+=key+'->'+obj[key] + ' ';
  return s;
}

function C(obj,s='') {
  const map = new Map(Object.entries(obj));
	for (let [key,value] of map) s+=key+'->'+value + ' ';
  return s;
}

function D(obj,s='') {
  let o = { 
    ...obj,
    *[Symbol.iterator]() {
      for (const i of Object.keys(this)) yield [i, this[i]];    
    }
  }
  for (let [key,value] of o) s+=key+'->'+value + ' ';
  return s;
}

function E(obj,s='') {
  let o = { 
    ...obj,
    *[Symbol.iterator]() {yield *Object.keys(this)}
  }
  for (let key of o) s+=key+'->'+o[key] + ' ';
  return s;
}

function F(obj,s='') {
	for (let key of Object.keys(obj)) s+=key+'->'+obj[key]+' ';
  return s;
}

function G(obj,s='') {
	for (let [key, value] of Object.entries(obj)) s+=key+'->'+value+' ';
  return s;
}

function H(obj,s='') {
	for (let key of Object.getOwnPropertyNames(obj)) s+=key+'->'+obj[key]+' ';
  return s;
}

function I(obj,s='') {
	for (const key of Reflect.ownKeys(obj)) s+=key+'->'+obj[key]+' ';
  return s;
}

function J(obj,s='') {
  let keys = Object.keys(obj);
	for(let i = 0; i < keys.length; i++){
    let key = keys[i];
    s+=key+'->'+obj[key]+' ';
  }
  return s;
}

function K(obj,s='') {
  var keys = Object.keys(obj), len = keys.length, i = 0;
  while (i < len) {
    let key = keys[i];
    s+=key+'->'+obj[key]+' ';
    i += 1;
  }
  return s;
}

function L(obj,s='') {
  Object.keys(obj).forEach(key=> s+=key+'->'+obj[key]+' ' );
  return s;
}

function M(obj,s='') {
  Object.entries(obj).forEach(([key, value]) => s+=key+'->'+value+' ');
  return s;
}

function N(obj,s='') {
  Object.getOwnPropertyNames(obj).forEach(key => s+=key+'->'+obj[key]+' ');
  return s;
}

function O(obj,s='') {
  Reflect.ownKeys(obj).forEach(key=> s+=key+'->'+obj[key]+' ' );
  return s;
}



// TEST

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};
let log = (name,f) => console.log(`${name} ${f(p)}`)

log('A',A);
log('B',B);
log('C',C);
log('D',D);
log('E',E);
log('F',F);
log('G',G);
log('H',H);
log('I',I);
log('J',J);
log('K',K);
log('L',L);
log('M',M);
log('N',N);
log('O',O);
This snippet only presents choosen solutions

А вот результат для мелких объектов на хроме

enter image description here

avatar
AmerllicA
22 февраля 2020 в 20:38
6

Хороший способ зацикливания на перечисляемом объекте JavaScript, который может быть отличным и обычным для ReactJS, - это использование Object.keys или Object.entries с использованием функции map. как показано ниже:

// assume items:

const items = {
  first: { name: 'phone', price: 400 },
  second: { name: 'tv', price: 300 },
  third: { name: 'sofa', price: 250 },
};

Для зацикливания и отображения некоторого пользовательского интерфейса на ReactJS действуйте, как показано ниже:

~~~
<div>
  {Object.entries(items).map(([key, ({ name, price })]) => (
    <div key={key}>
     <span>name: {name}</span>
     <span>price: {price}</span>
    </div>
  ))}
</div>

На самом деле, я использую назначение деструктуризации дважды, один раз для получения key, один раз для получения name и price.

Mob_Abominator
19 августа 2020 в 05:52
0

Я именно это искал, так как работаю с React и как циклы for не работают внутри <Fragment>, это идеальное решение. Большое спасибо

AmerllicA
19 августа 2020 в 07:32
0

Уважаемый @Mob_Abominator, спасибо за ваш приятный комментарий, я рад слышать, что он полезен для вас. но я не понимаю how for loops don't work inside <Fragment>. Остается ли проблема? если есть, пожалуйста, оставьте вопрос и скажите мне, я отвечу. если ничего не останется, и теперь с тобой все в порядке. пожалуйста, оставьте свой голос за этот пост. благодаря.

avatar
akhtarvahid
4 января 2020 в 11:13
8

Несколько способов итерации объекта в javascript

Использование для ... в цикле

 var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};
for (let key in p){
   if(p.hasOwnProperty(key)){
     console.log(`${key} : ${p[key]}`)
   }
}

Использование для ... из цикла

 var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};
for (let key of Object.keys(p)){
     console.log(`key: ${key} & value: ${p[key]}`)
}

Использование forEach () с Object.keys , Object.values ​​, Object201357120590>Object2012035590>

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};
Object.keys(p).forEach(key=>{
   console.log(`${key} : ${p[key]}`);
});
Object.values(p).forEach(value=>{
   console.log(value);
});
Object.entries(p).forEach(([key,value])=>{
    console.log(`${key}:${value}`)
})

avatar
Nicolas Cabanas
30 октября 2019 в 21:05
9

Использование for-of на Object.keys()

Нравится:

let object = {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
};

for (let key of Object.keys(object)) {
  console.log(key + " : " + object[key])
}
avatar
Onera
13 августа 2019 в 07:14
16

Вы также можете использовать Object.keys () и перебирать ключи объекта, как показано ниже, чтобы получить значение:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).forEach((key)=> {
 console.log(key +' -> '+ p[key]);
});
Swap-IOS-Android
18 сентября 2019 в 14:39
0

Вы сэкономили мое время, спасибо

Onera
26 сентября 2019 в 09:52
0

Рад знать :)

avatar
Randhir Rawatlal
8 июня 2019 в 18:26
-1

Если ваше приложение создает строку, хорошей комбинацией будет Object.keys, implode и метод массива .map. Например, если у нас есть объект json типа

var data = {
    key1: 10,
    key2: 'someString',
    key3: 3000
}

.. и мы хотим создать «Значения: key1 = 10, key2 = someString, key3 = 3000».

Мы можем сделать это в одной строке кода:

var str = `The values are ${implode(', ', Object.keys(data).map(function(key){return `${key} = ${data[key]}`}))}.`;

Implode сворачивает массив в строку с разделителем (первым аргументом), вставленным между элементами; .map выполняет итерацию по массиву, возвращающему массив, а Object.keys довольно хорошо проработан другими ответами.

avatar
PythonProgrammi
7 февраля 2019 в 05:28
1

Вот как пройти через объект javascript и поместить данные в таблицу.

<body>
<script>
function createTable(objectArray, fields, fieldTitles) {
  let body = document.getElementsByTagName('body')[0];
  let tbl = document.createElement('table');
  let thead = document.createElement('thead');
  let thr = document.createElement('tr');

  for (p in objectArray[0]){
    let th = document.createElement('th');
    th.appendChild(document.createTextNode(p));
    thr.appendChild(th);
    
  }
 
  thead.appendChild(thr);
  tbl.appendChild(thead);

  let tbdy = document.createElement('tbody');
  let tr = document.createElement('tr');
  objectArray.forEach((object) => {
    let n = 0;
    let tr = document.createElement('tr');
    for (p in objectArray[0]){
      var td = document.createElement('td');
      td.appendChild(document.createTextNode(object[p]));
      tr.appendChild(td);
      n++;
    };
    tbdy.appendChild(tr);    
  });
  tbl.appendChild(tbdy);
  body.appendChild(tbl)
  return tbl;
}

createTable([
              {name: 'Banana', price: '3.04'}, // k[0]
              {name: 'Orange', price: '2.56'},  // k[1]
              {name: 'Apple', price: '1.45'}
           ])
</script>
avatar
nrb
24 октября 2018 в 19:51
3

Object.entries() функция:

var p = {
	    "p1": "value1",
	    "p2": "value2",
	    "p3": "value3"
	};

for (var i in Object.entries(p)){
	var key = Object.entries(p)[i][0];
	var value = Object.entries(p)[i][1];
	console.log('key['+i+']='+key+' '+'value['+i+']='+value);
}
nrb
29 октября 2018 в 19:22
0

пожалуйста, не удаляйте фрагмент, если вы редактируете мою запись

Kamil Kiełczewski
5 марта 2020 в 10:25
0

для увеличения производительности используйте var e=Object.entries(p) и везде измените Object.entries(p) на e

avatar
Ankit
11 сентября 2018 в 05:55
11

В последней версии скрипта ES вы можете сделать что-то вроде этого:

let p = {foo: "bar"};
for (let [key, value] of Object.entries(p)) {
  console.log(key, value);
}
Harsh Phoujdar
15 сентября 2020 в 20:22
0

Работает автономно, но не работает, если эта функция возвращает значение для каждого условия

avatar
T.J. Crowder
10 июля 2018 в 10:39
60

Предисловие:

  • Свойства объекта могут быть собственными (свойство находится на самом объекте) или унаследованными (не на самом объекте, на одном из его прототипов).
  • Свойства объекта могут быть перечислимыми или неперечисляемыми . Неперечислимые свойства исключены из множества перечислений / массивов свойств.
  • Имена свойств могут быть строками или символами. Свойства, имена которых являются символами, исключены из множества перечислений / массивов свойств.

Здесь, в 2018 году, ваши варианты циклического перебора свойств объекта (некоторые примеры следуют за списком):

  1. for-in [MDN, spec] - структура цикла, которая перебирает имена наследуемых свойств <194750015966 объекта <1947500159> , чьи имена - строки
  2. Object.keys [MDN, spec] - функция, предоставляющая массив имен объектов , , объекта <475001500966> свойства, имена которых являются строками.
  3. Object.values [ MDN, spec] - Функция, предоставляющая массив значений и объекта <Reflect.ownKeys662159156 >, перечислимые свойства.
  4. Object.entries [MDN, spec] - Функция, предоставляющая массив имен и собственных значений объекта <228 , перечислимые свойства (каждая запись в массиве представляет собой массив [name, value]).
  5. Object.getOwnPropertyNames [MDN, spec] - Функция, предоставляющая массив имен свойств объекта , не относящихся к четным перечислимые), имена которых являются строками.
  6. Object.getOwnPropertySymbols [MDN, spec] - функция, предоставляющая массив имен свойств объекта <4150015966249>, не относящихся к собственному объекту перечислимые), имена которых являются символами.
  7. Reflect.ownKeys [MDN, spec] - Функция, предоставляющая массив имен свойств объекта <41500159662>, не относящихся к собственному объекту перечислимые), независимо от того, являются ли эти имена строками или символами.
  8. Если вы хотите всех свойств объекта, включая неперечислимые унаследованные, вам необходимо использовать цикл и Object.getPrototypeOf [MDN, <468966267>, <468966267 >] и используйте Object.getOwnPropertyNames, Object.getOwnPropertySymbols или Reflect.ownKeys для каждого объекта в цепочке прототипов (пример внизу этого ответа).

Со всеми из них, кроме for-in, вы должны использовать какую-то конструкцию цикла для массива (for, for-of, forEach и т. Д.).

Примеры:

for-in:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name in o) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.keys (с циклом for-of, но вы можете использовать любую конструкцию цикла) :

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.keys(o)) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.values:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const value of Object.values(o)) {
    console.log(`${value}`);
}

Object.entries:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const [name, value] of Object.entries(o)) {
    console.log(`${name} = ${value}`);
}

Object.getOwnPropertyNames:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertyNames(o)) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.getOwnPropertySymbols:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertySymbols(o)) {
    const value = o[name];
    console.log(`${String(name)} = ${value}`);
}

Reflect.ownKeys:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Reflect.ownKeys(o)) {
    const value = o[name];
    console.log(`${String(name)} = ${value}`);
}

Все свойства , включая унаследованные неперечислимые:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (let depth = 0, current = o; current; ++depth, current = Object.getPrototypeOf(current)) {
    for (const name of Reflect.ownKeys(current)) {
        const value = o[name];
        console.log(`[${depth}] ${String(name)} = ${String(value)}`);
    }
}
.as-console-wrapper {
  max-height: 100% !important;
}
serraosays
22 апреля 2019 в 04:46
1

Хорошее добавление ienumerable / non-ienumerable свойств объекта.

avatar
yehonatan yehezkel
9 июля 2018 в 16:15
5

, начиная с ES06, вы можете получать значения объекта в виде массива с помощью

let arrValues = Object.values( yourObject) ;

он возвращает массив значений объекта и не извлекает значения из прототипа !!

MDN DOCS Object.values ​​()

и для ключей (все ответы уже были до меня здесь)

let arrKeys   = Object.keys(yourObject);
Sean Lindo
21 августа 2018 в 19:03
0

Ответы требуют решения, которое возвращает как ключи, так и значения.

avatar
senthil
26 июня 2018 в 14:34
5

    var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"},
{"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}]
for(var value in p) {
    for (var key in value) {
        if (p.hasOwnProperty(key)) {
            console.log(key + " -> " + p[key]);
        }
    }
}
Marek Bernád
14 октября 2018 в 12:27
0

json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }

avatar
Zectbumo
26 февраля 2018 в 02:42
-1
  • одноуровневый отступ
  • одиночный комплект скоб
  • максимальная совместимость с браузером
  • безопасный hasOwnProperty

var p = {"p1": "value1", "p2": "value2", "p3": "value3"};

for (var key in p) if (p.hasOwnProperty(key)) {
  var value = p[key];
  console.log(key, value);
}
avatar
Matas Vaitkevicius
7 февраля 2018 в 11:22
0

Если вы хотите перебирать только свойства, используйте один из ответов выше, однако, если вы хотите перебирать все, включая функции, вы можете использовать Object.getOwnPropertyNames (obj)

for (let o of Object.getOwnPropertyNames(Math)) {
  console.log(o);
}

Я иногда использую это для быстрого тестирования всех функций на объектах с простыми входами и выходами.

Barkermn01
25 июня 2019 в 11:17
1

Я не знаю, почему он был отклонен, но, глядя на это сейчас, это идеально, потому что в javascript «методы» - это просто свойства объекта в JS let test = function(){ this.method = () => {}; } console.log(new test());

avatar
Harsh Patel
20 декабря 2017 в 04:42
10

Вот еще один метод итерации по объекту.

   var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


Object.keys(p).forEach(key => { console.log(key, p[key]) })
Rolf
10 марта 2018 в 00:17
3

Это довольно круто, однако для больших объектов метод for может быть более производительным.

avatar
Muhammad Usman
16 ноября 2017 в 20:04
9

Метод Object.keys() возвращает массив собственных перечислимых свойств данного объекта. Подробнее об этом здесь

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
avatar
Dan Alboteanu
13 ноября 2017 в 16:05
0

Объект становится итератором, когда он реализует метод .next ()

const james = {
  name: 'James',
  height: `5'10"`,
  weight: 185,

  [Symbol.iterator]() {
    let properties = []
    for (let key of Object.keys(james)) {
      properties.push(key);
    }

    index = 0;
    return {
      next: () => {
        let key = properties[index];
        let value = this[key];
        let done = index >= properties.length - 1;
        index++;
        return {
          key,
          value,
          done
        };
      }
    };
  }

};


const iterator = james[Symbol.iterator]();

console.log(iterator.next().value); // 'James'
console.log(iterator.next().value); // `5'10`
console.log(iterator.next().value); // 185
avatar
Jaime Rios
10 октября 2017 в 18:57
1

У меня была аналогичная проблема при использовании Angular, вот решение, которое я нашел.

Шаг 1. Получите все ключи объекта. используя Object.keys. Этот метод возвращает массив перечислимых свойств данного объекта.

Шаг 2. Создайте пустой массив. Здесь будут жить все свойства, поскольку ваш новый цикл ngFor будет указывать на этот массив, мы должны поймать их все. Шаг 3. Итеративно отбросить все ключи и вставить каждый из них в созданный вами массив. Вот как это выглядит в коде.

    // Evil response in a variable. Here are all my vehicles.
let evilResponse = { 
  "car" : 
    { 
       "color" : "red",
       "model" : "2013"
    },
   "motorcycle": 
    { 
       "color" : "red",
       "model" : "2016"
    },
   "bicycle": 
    { 
       "color" : "red",
       "model" : "2011"
    }
}
// Step 1. Get all the object keys.
let evilResponseProps = Object.keys(evilResponse);
// Step 2. Create an empty array.
let goodResponse = [];
// Step 3. Iterate throw all keys.
for (prop of evilResponseProps) { 
    goodResponse.push(evilResponseProps[prop]);
}

Вот ссылка на исходный пост. https://medium.com/@papaponmx/looping-over-object-properties-with-ngfor-in-angular-869cd7b2ddcc

avatar
Biber
22 ноября 2016 в 20:46
7

Вы можете добавить простую функцию forEach ко всем объектам, чтобы вы могли автоматически перебирать любой объект:

Object.defineProperty(Object.prototype, 'forEach', {
    value: function (func) {
        for (var key in this) {
            if (!this.hasOwnProperty(key)) {
                // skip loop if the property is from prototype
                continue;
            }
            var value = this[key];
            func(key, value);
        }
    },
    enumerable: false
});

Для тех, кому не нравится метод " для ... в ":

Object.defineProperty(Object.prototype, 'forEach', {
    value: function (func) {
        var arr = Object.keys(this);
        for (var i = 0; i < arr.length; i++) {
            var key = arr[i];
            func(key, this[key]);
        }
    },
    enumerable: false
});

Теперь вы можете просто позвонить:

p.forEach (function(key, value){
    console.log ("Key: " + key);
    console.log ("Value: " + value);
});

Если вы не хотите конфликтовать с другими методами forEach, вы можете назвать его своим уникальным именем.

Moritz
6 января 2017 в 13:06
3

Изменение прототипов встроенных объектов (например, Object) обычно считается антипаттерном, поскольку оно может легко вызвать конфликты с другим кодом. Так что рану не рекомендую делать это таким образом.

avatar
Bamieh
20 сентября 2016 в 09:04
5

В ES6 у нас есть хорошо известные символы для раскрытия некоторых ранее внутренних методов, вы можете использовать их, чтобы определить, как работают итераторы для этого объекта:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3",
    *[Symbol.iterator]() {
        yield *Object.keys(this);
    }
};

[...p] //["p1", "p2", "p3"]

это даст тот же результат, что и использование for ... в цикле es6.

for(var key in p) {
    console.log(key);
}

Но важно знать возможности, которые у вас есть теперь при использовании es6!

ooo
3 мая 2019 в 05:32
1

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

avatar
Artyom Pranovich
1 сентября 2016 в 20:15
4

Учитывая ES6, я бы хотел добавить свою ложку сахара и предоставить еще один подход для итерации свойств объекта.

Поскольку простой объект JS не итерируемый сразу из коробки, мы не можем использовать цикл for..of для итерации по его содержимому. Но никто не может остановить нас , чтобы сделать его повторяемым .

У нас есть объект book.

let book = {
  title: "Amazing book",
  author: "Me",
  pages: 3
}

book[Symbol.iterator] = function(){

  let properties = Object.keys(this); // returns an array with property names
  let counter = 0;
  let isDone = false;

  let next = () => {
    if(counter >= properties.length){
      isDone = true;
    }
    return { done: isDone, value: this[properties[counter++]] }
  }

  return { next };
}

Поскольку мы сделали это, мы можем использовать его так:

for(let pValue of book){
  console.log(pValue);
}
------------------------
Amazing book
Me
3

Или, если вы знаете мощность генераторов ES6 , вы, безусловно, можете сделать приведенный выше код намного короче.

book[Symbol.iterator] = function *(){

  let properties = Object.keys(this);
  for (let p of properties){
    yield this[p];
  }

}

Конечно, вы можете применить такое поведение ко всем объектам, сделав Object итеративным на уровне prototype.

Object.prototype[Symbol.iterator] = function() {...}

Кроме того, объекты, соответствующие итеративному протоколу, могут использоваться с новой функцией ES2015 оператором распространения, поэтому мы можем считывать значения свойств объекта в виде массива.

let pValues = [...book];
console.log(pValues);
-------------------------
["Amazing book", "Me", 3]

Или вы можете использовать деструктурирующее присвоение:

let [title, , pages] = book; // notice that we can just skip unnecessary values
console.log(title);
console.log(pages);
------------------
Amazing book
3

Вы можете проверить JSFiddle со всем кодом, который я предоставил выше.

Pika
8 сентября 2016 в 03:34
0

Я обнаружил, что код будет генерировать значения, но без ключей. Можно ли перебирать значения с помощью ключей?

Artyom Pranovich
8 сентября 2016 в 13:33
0

Да, ты можешь. Просто верните «yield [key, obj [key]];» из вашей функции-генератора, а затем используйте его следующим образом: "for (let [key, value] of {}) {}"

avatar
FieryCod
27 августа 2016 в 09:06
30

Поскольку es2015 становится все более популярным, я публикую этот ответ, который включает использование генератора и итератора для плавного перебора пар [key, value]. Как это возможно на других языках, например на Ruby.

Хорошо, вот код:

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
  [Symbol.iterator]: function*() {
    for (const i of Object.keys(this)) {
      yield [i, this[i]];
    }
  }
};

for (const [k, v] of MyObject) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Всю информацию о том, как сделать итератор и генератор, можно найти на странице разработчика Mozilla.

Надеюсь, это кому-то помогло.

EDIT:

ES2017 будет включать Object.entries, что упростит итерацию пар [key, value] в объектах. Теперь известно, что он будет частью стандарта в соответствии с информацией этапа ts39.

Думаю, пора обновить свой ответ, чтобы он стал еще свежее, чем сейчас.

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
};

for (const [k, v] of Object.entries(MyObject)) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Подробнее об использовании можно узнать на MDN страница

Dean Radcliffe
28 сентября 2017 в 16:36
0

Мне это кажется совершенно лишним / ненужным. Вы бы добавили его к каждому объекту в вашей системе? Я думал, что итератор нужен для того, чтобы вы могли сделать for (const [k, v] of myObject). Это просто выглядит как дополнительный код, не дающий дополнительной ценности.

avatar
Tadas V.
22 июля 2016 в 03:48
4

Если кому-то нужно пройти через arrayObjects с условием :

var arrayObjects = [{"building":"A", "status":"good"},{"building":"B","status":"horrible"}];

for (var i=0; i< arrayObjects.length; i++) {
  console.log(arrayObjects[i]);
  
  for(key in arrayObjects[i]) {      
    
      if (key == "status" && arrayObjects[i][key] == "good") {
        
          console.log(key + "->" + arrayObjects[i][key]);
      }else{
          console.log("nothing found");
      }
   }
}
avatar
Hashbrown
28 июня 2016 в 09:42
18

Интересно, что люди в этих ответах коснулись как Object.keys(), так и for...of, но никогда не объединяли их:

var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
    console.log(key + ':' + map[key]);

Вы не можете просто for...of использовать Object, потому что это не итератор, а for...index или .forEach() использовать Object.keys() некрасиво / неэффективно.
Я рад, что большинство людей воздерживаются от for...in (с проверкой или без проверки .hasOwnProperty()), так как это также немного беспорядочно, поэтому, помимо моего ответа выше, я здесь, чтобы сказать ...


Вы можете заставить обычные ассоциации объектов повторяться! Вести себя так же, как Map с прямым использованием причудливого for...of
DEMO, работающего в Chrome и FF (я предполагаю только ES6)

var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
    //key:value
    console.log(pair[0] + ':' + pair[1]);

//or
for (let [key, value] of ordinaryObject)
    console.log(key + ':' + value);

Если вы добавили мою прокладку ниже:

//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
    var keys = Object.keys(this)[Symbol.iterator]();
    var obj = this;
    var output;
    return {next:function() {
        if (!(output = keys.next()).done)
            output.value = [output.value, obj[output.value]];
        return output;
    }};
};

Без необходимости создавать настоящий объект Map, который не имеет приятного синтаксического сахара.

var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
    console.log(pair[0] + ':' + pair[1]);

Фактически, с этой прокладкой, если вы все еще хотели воспользоваться преимуществами других функций Map (без их объединения), но по-прежнему хотели использовать аккуратную нотацию объектов, поскольку теперь объекты являются итеративными, вы теперь можете просто создать Map с него!

//shown in demo
var realMap = new Map({well:'hello', there:'!'});

Для тех, кто не любит использовать шайбы или возиться с prototype в целом, не стесняйтесь делать функцию вместо этого в окне, называя ее чем-то вроде getObjIterator() тогда;

//no prototype manipulation
function getObjIterator(obj) {
    //create a dummy object instead of adding functionality to all objects
    var iterator = new Object();

    //give it what the shim does but as its own local property
    iterator[Symbol.iterator] = function() {
        var keys = Object.keys(obj)[Symbol.iterator]();
        var output;

        return {next:function() {
            if (!(output = keys.next()).done)
                output.value = [output.value, obj[output.value]];
            return output;
        }};
    };

    return iterator;
}

Теперь вы можете просто вызвать ее как обычную функцию, все остальное не затронуто

var realMap = new Map(getObjIterator({well:'hello', there:'!'}))

или

for (let pair of getObjIterator(ordinaryObject))

Нет причин, по которым это не сработает.

Добро пожаловать в будущее.

Hashbrown
22 июля 2016 в 06:57
2

Дело в точке. Пока люди прокручивают страницу вниз и находят ее полезной, это все, что имеет значение. Обычно это я пытаюсь что-то сделать, мне не нравится то, что я вижу в Интернете, в конечном итоге выясняю это, а затем возвращаюсь, чтобы поделиться. Это хороший док, я на самом деле наткнулся на свои собственные ответы, прежде чем искать в Google то, о чем полностью забыл!

Janus Troelsen
30 сентября 2016 в 10:19
0

@HelpMeStackOverflowMyOnlyHope Лично мне не нравится изменять прототипы объектов, которые я не определял сам.

Hashbrown
30 сентября 2016 в 12:58
0

@JanusTroelsen, ты вообще читал весь ответ? For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;

noɥʇʎԀʎzɐɹƆ
14 июня 2018 в 15:17
0

Обратите внимание, что этот метод не работает с простыми объектами, но, тем не менее, полезен.

Hashbrown
15 июня 2018 в 06:47
0

он действительно работает для простых объектов, в этом буквально весь смысл (а также имена переменных, такие как ordinaryObject, чтобы подчеркнуть, что магия все еще работает для этих типов). Вы проверяли демонстрации; что у тебя не работает, @ noɥʇʎԀʎzɐɹƆ? (P.S. ваше изображение в профиле SE - босс)

noɥʇʎԀʎzɐɹƆ
15 июня 2018 в 20:52
0

Моя вина, я не прочитал деталь на регулировочной шайбе. Это не работает для простых объектов без изменения прототипа.

Hashbrown
16 июня 2018 в 03:18
0

Опять же, @ noɥʇʎԀʎzɐɹƆ, неправда: DEMO. Взгляните на мой ответ на @Janus. Хм, два человека боролись и сказали это сейчас, поэтому я обновлю ответ, чтобы сделать его лучше, я, возможно, не объяснил, как адаптировать технику, чтобы не нуждаться в манипуляциях с прототипом должным образом

avatar
Nicolas Bouvrette
18 июня 2016 в 02:11
6

Циклы могут быть довольно интересными при использовании чистого JavaScript. Похоже, что только ECMA6 (новая спецификация JavaScript 2015 г.) смог контролировать циклы. К сожалению, пока я пишу это, и браузеры, и популярная интегрированная среда разработки (IDE) все еще изо всех сил пытаются полностью поддерживать новые навороты.

Вот как выглядит цикл объекта JavaScript до ECMA6:

for (var key in object) {
  if (p.hasOwnProperty(key)) {
    var value = object[key];
    console.log(key); // This is the key;
    console.log(value); // This is the value;
  }
}

Кроме того, я знаю, что это выходит за рамки этого вопроса, но в 2011 году ECMAScript 5.1 добавил метод forEach только для массивов, который в основном создал новый улучшенный способ циклического перебора массивов, оставив при этом не повторяющиеся объекты со старыми многословный и запутанный цикл for. Но странно то, что этот новый метод forEach не поддерживает break, что привело к множеству других проблем.

По сути, в 2011 году не было реального надежного способа зацикливания в JavaScript, кроме того, что многие популярные библиотеки (jQuery, Underscore и т. Д.) Решили повторно реализовать.

По состоянию на 2015 год у нас теперь есть улучшенный нестандартный способ зацикливания (и прерывания) любого типа объекта (включая массивы и строки). Вот как в конечном итоге будет выглядеть цикл в JavaScript, когда рекомендация станет основной:

for (let [key, value] of Object.entries(object)) {
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

Обратите внимание, что большинство браузеров не будут поддерживать приведенный выше код по состоянию на 18 июня 2016 года. Даже в Chrome вам необходимо включить этот специальный флаг, чтобы он работал: chrome://flags/#enable-javascript-harmony

Пока это не станет новым стандартом, старый метод все еще можно использовать, но есть альтернативы в популярных библиотеках или даже облегченные альтернативы для тех, кто не использует ни одну из этих библиотек.

abalter
18 июня 2016 в 06:24
0

Не могли бы вы дать скрипку этой работы? Вот моя попытка. jsfiddle.net/abalter/sceeb211

Nicolas Bouvrette
18 июня 2016 в 12:56
0

@abalter Извините, я обнаружил опечатку в моем коде. Я исправил это и обновил ваш JsFiddle здесь: jsfiddle.net/sceeb211/2

abalter
18 июня 2016 в 16:07
0

Я в хроме и получаю Uncaught TypeError: Object.entries is not a function. Это еще не реализовано в Chrome?

Nicolas Bouvrette
18 июня 2016 в 16:39
0

@abalter Это так. Убедитесь, что у вас установлена ​​версия Chrome 51 и вы включили флаг, как описано в моем редактировании и комментариях Jsfiddle. Вы можете проверить подробности здесь: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

abalter
19 июня 2016 в 05:39
0

Извини, что пропустил это по поводу флага. Я вижу, что это еще не полностью реализованная функция.

Nicolas Bouvrette
19 июня 2016 в 11:38
0

@abalter Принять его еще рано. Я не уверен, что вы пытаетесь сделать, но смотрели ли вы на альтернативные решения, такие как github.com/nbouvrette/forEach

abalter
19 июня 2016 в 21:16
0

Я обычно использую $.each или forEach вместе с hasOwnProperty.

Tjorriemorrie
12 июля 2016 в 14:56
0

Следует упомянуть, что это также уместно при использовании Babel.

avatar
Marius Bakowski
14 апреля 2016 в 11:27
-3

Начиная с ES2015, вы можете использовать цикл for of для прямого доступа к элементу:

// before ES2015
for(var key of elements){
  console.log(elements[key]);
}


// ES2015
for(let element of elements){
  console.log(element);
}

Надеюсь, это кому-то поможет.

Evan Carroll
8 июня 2016 в 17:29
2

Мало того, что это не помогает, это не точно. For ... of работает, только если элементы определяют итератор. Это верно для массивов, наборов и карт, но не для объектов.

Hashbrown
28 июня 2016 в 09:43
0

вы действительно можете заставить эту работу, @EvanCarroll

avatar
Dheeraj Vepakomma
12 сентября 2015 в 16:31
4

Если вы хотите перебрать неперечислимые свойства , вы также можете использовать Object.getOwnPropertyNames(obj) для возврата массива перечислимых не) найден непосредственно на заданном объекте.

var obj = Object.create({}, {
  // non-enumerable property
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});

obj.foo = 1; // enumerable property

Object.getOwnPropertyNames(obj).forEach(function (name) {
  document.write(name + ': ' + obj[name] + '<br/>');
});
Pierce
11 марта 2016 в 19:49
2

Это фантастика, спасибо, что разместили этот ответ. Мне нужно было проанализировать объект Error, и я не мог получить доступ к свойствам в цикле или вызове _.forIn(err). Использование Object.getOwnPropertyNames(err) позволило мне получить доступ ко всем частям Error, к которым я не мог добраться раньше. Спасибо!

avatar
Lewis
9 июля 2015 в 08:22
5

Я бы сделал это, а не проверял obj.hasOwnerProperty в каждом цикле for ... in.

var obj = {a : 1};
for(var key in obj){
    //obj.hasOwnProperty(key) is not needed.
    console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
    throw new Error("Please don't extend the native object");
}
avatar
Dmitry Sheiko
22 июня 2015 в 09:52
13

Object.keys (obj): массив

извлекает все ключи со строковыми значениями всех перечислимых собственных (ненаследуемых) свойств.

Таким образом, он дает тот же список ключей, что и вы, проверяя каждый ключ объекта с помощью hasOwnProperty. Вам не нужна эта дополнительная тестовая операция, а Object.keys( obj ).forEach(function( key ){}) должен быть быстрее. Докажем это:

var uniqid = function(){
			var text = "",
					i = 0,
					possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
			for( ; i < 32; i++ ) {
					text += possible.charAt( Math.floor( Math.random() * possible.length ) );
			}
			return text;
		}, 
		CYCLES = 100000,
		obj = {}, 
		p1,
		p2,
		p3,
		key;

// Populate object with random properties
Array.apply( null, Array( CYCLES ) ).forEach(function(){
	obj[ uniqid() ] = new Date()
});

// Approach #1
p1 = performance.now();
Object.keys( obj ).forEach(function( key ){
	var waste = obj[ key ];
});

p2 = performance.now();
console.log( "Object.keys approach took " + (p2 - p1) + " milliseconds.");

// Approach #2
for( key in obj ) {
	if ( obj.hasOwnProperty( key ) ) {
		var waste = obj[ key ];
	}
}

p3 = performance.now();
console.log( "for...in/hasOwnProperty approach took " + (p3 - p2) + " milliseconds.");

В моем Firefox я получил следующие результаты

  • Подход Object.keys занял 40,21101451665163 миллисекунды.
  • для ... in / hasOwnProperty подход занял 98,26163508463651 миллисекунды.

PS. в Chrome разница еще больше http://codepen.io/dsheiko/pen/JdrqXa

PS2: в ES6 (EcmaScript 2015) вы можете лучше перебирать итерируемый объект:

let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
    console.log(pair);
}

// OR 
let map = new Map([
    [false, 'no'],
    [true,  'yes'],
]);
map.forEach((value, key) => {
    console.log(key, value);
});
Hashbrown
28 июня 2016 в 09:47
0

если вам не хочется отказываться от обозначения {}, вы все равно можете использовать of, не создавая карты

avatar
mohamed-ibrahim
21 апреля 2015 в 12:02
11

Только код JavaScript без зависимостей:

var p = {"p1": "value1", "p2": "value2", "p3": "value3"};
keys = Object.keys(p);   // ["p1", "p2", "p3"]

for(i = 0; i < keys.length; i++){
  console.log(keys[i] + "=" + p[keys[i]]);   // p1=value1, p2=value2, p3=value3
}
avatar
B.F.
8 июня 2014 в 05:55
-6

Потому что спрашивающие [' конечная цель - пройти через несколько пар ключ-значение '] и, наконец, не искать зацикливания.

var p ={"p1":"value1","p2":"value2","p3":"value3"};
if('p1' in p){
  var val=p['p1'];
  ...
}
Sebastian
5 августа 2014 в 06:40
3

Нет! Он написал: «Теперь я хочу перебрать все элементы p», поэтому ему действительно нужен цикл, как в его принятом ответе.

avatar
Pencroff
16 ноября 2013 в 19:59
55

В ECMAScript 5 у вас есть новый подход к полям итерации литерала - Object.keys

Более подробную информацию вы можете увидеть на MDN

Мой выбор ниже как более быстрое решение в текущих версиях браузеров (Chrome30, IE10, FF25)

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

Вы можете сравнить производительность этого подхода с различными реализациями на jsperf.com:

Поддержка браузера вы можете увидеть в таблице совместимости Kangax

Для старого браузера у вас есть простой и полный полифил

UPD:

сравнение производительности для всех наиболее популярных случаев в этом вопросе на perfjs.info:

итерация литерала объекта

Jamie Hutber
20 марта 2014 в 23:05
1

Действительно, я просто хотел опубликовать этот метод. Но ты меня опередил :(

avatar
VisioN
20 января 2013 в 17:58
260

Вопрос не будет полным, если мы не упомянем об альтернативных методах перебора объектов.

В настоящее время многие известные библиотеки JavaScript предоставляют свои собственные методы для итерации по коллекциям, то есть по массивам, , объектам ​​и объектам, подобным массивам . Эти методы удобны в использовании и полностью совместимы с любым браузером.

  1. Если вы работаете с jQuery , вы можете использовать метод jQuery.each(). Его можно использовать для беспрепятственного перебора как объектов, так и массивов:

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. В Underscore.js вы можете найти метод _.each(), который выполняет итерацию по списку элементов, возвращая каждый в свою очередь в предоставленную функцию (обратите внимание на порядок аргументы в функции iteratee !):

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Dash предоставляет несколько методов для перебора свойств объекта. Базовый _.forEach() (или его псевдоним _.each()) полезен для циклического перебора как объектов, так и массивов, однако (!) Объекты со свойством length обрабатываются как массивы, и во избежание такого поведения предлагается использовать методы _.forIn() и _.forOwn() (они также имеют аргумент value, идущий первым):

    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    

    _.forIn() выполняет итерацию по собственным и унаследованным перечислимым свойствам объекта, в то время как _.forOwn() выполняет итерацию только по собственному , проверяя свойства объекта (в основном, по функциям) <830522> (в основном) . Для простых объектов и объектных литералов подойдет любой из этих методов.

Обычно все описанные методы имеют одинаковое поведение с любыми предоставленными объектами. Помимо использования собственного цикла for..in, обычно быстрее , чем любая абстракция, например jQuery.each(), эти методы значительно проще в использовании, требуют меньше кода и обеспечивают лучшую обработку ошибок.

Ravi Ram
8 июня 2013 в 14:41
4

Чтобы перейти к значению: $ .each (obj, function (key, value) {console.log (value.title);});

ppasler
8 сентября 2017 в 07:24
2

Забавно, как подчеркивание и jquery меняли параметры :)

avatar
strider
9 декабря 2012 в 05:05
20

через прототип с forEach () , который должен пропускать цепочку прототипов свойства: <14981308163

Object.prototype.each = function(f) {
    var obj = this
    Object.keys(obj).forEach( function(key) { 
        f( key , obj[key] ) 
    });
}


//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3

David Harkness
23 июня 2014 в 21:40
2

Будьте осторожны с прототипом: obj = { print: 1, each: 2, word: 3 } производит TypeError: number is not a function. Использование forEach для сопоставления с аналогичной функцией Array может несколько снизить риск.

avatar
ParaMeterz
21 февраля 2012 в 11:22
16

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " = " + p[key]);
    }
}
<p>
  Output:<br>
  p1 = values1<br>
  p2 = values2<br>
  p3 = values3
</p>
avatar
Francis Lewis
18 августа 2011 в 20:50
21

После просмотра всех ответов здесь, hasOwnProperty не требуется для моего собственного использования, потому что мой объект json чистый; действительно нет смысла добавлять дополнительную обработку javascript. Это все, что я использую:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
G-Wiz
13 января 2012 в 20:15
18

Чистый объект JSON или нет, не имеет значения. Если в любое другое время какой-либо код устанавливает свойство на Object.prototype, тогда оно будет нумероваться как for..in. Если вы уверены, что не используете какие-либо библиотеки, которые делают это, вам не нужно вызывать hasOwnProperty.

Juan Mendes
14 апреля 2016 в 11:37
4

Он может быть полностью чистым, если создан с помощью Object.create(null)

avatar
Axel Rauschmayer
20 апреля 2011 в 21:59
1224

В ECMAScript 5 вы можете объединить Object.keys() и Array.prototype.forEach():

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ECMAScript 6 добавляет for...of:

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ECMAScript 8 добавляет Object.entries(), что позволяет избежать поиска каждого значения в исходном объекте:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

Вы можете комбинировать for...of, деструктурирование и Object.entries:

for (const [key, value] of Object.entries(obj)) {
    console.log(key, value);
}

И Object.keys(), и Object.entries() повторяют свойства в том же порядке, что и цикл for...in, , но игнорируют цепочку прототипов . Итерируются только собственные перечислимые свойства объекта.

David Harkness
23 июня 2014 в 20:36
23

Почему в стандарте не было Object.forEach(obj, function (value, key) {...})? :( Конечно, obj.forEach(function...) был бы короче и дополнял бы Array.prototype.forEach, но это может привести к тому, что объекты будут определять собственное свойство forEach. Я полагаю, что Object.keys защищает от обратного вызова, изменяющего ключи объекта.

avatar
Andreas Grech
26 марта 2009 в 06:12
358

Вы должны использовать цикл for-in

Но будьте очень осторожны при использовании такого типа цикла, потому что он будет зациклить все свойства в цепочке прототипов .

Следовательно, при использовании циклов for-in всегда используйте метод hasOwnProperty, чтобы определить, действительно ли текущее свойство в итерации является свойством объекта, который вы проверяете:

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}
SystemicPlural
6 апреля 2011 в 09:55
31

Это лучше, чем решение levik, потому что оно позволяет основной логике быть только одним вложенным циклом, а не двумя; упрощая чтение кода. Хотя я бы потерял скобки вокруг продолжения; они лишние.

pimvdb
5 августа 2011 в 12:01
53

Я бы не стал удалять { } лично, потому что без них if немного неясно, что является частью if, а что нет. Но я думаю, это всего лишь вопрос мнения :)

Andreas Grech
5 августа 2011 в 12:21
34

Да, я предпочитаю оставить { }, в основном, чтобы избежать путаницы, если позже понадобится что-то добавить в область if.

Andreas Grech
11 ноября 2011 в 11:08
8

Прочитав мой предыдущий комментарий, я понял, что использовал неправильные термины, потому что сказал «if scope»; но имейте в виду, что JavaScript имеет только область действия. На самом деле я имел в виду «если блокировать».

eomeroff
19 июня 2013 в 08:56
0

«К сожалению, hasOwnProperty - это метод, а не оператор, поэтому в любом объекте его можно заменить другой функцией или даже значением, которое не является функцией»

avatar
Bryan
26 марта 2009 в 06:05
53

Вы можете просто перебирать его, например:

for (var key in p) {
  alert(p[key]);
}

Обратите внимание, что key не будет принимать значение свойства, это просто значение индекса.

Vatsal
2 июня 2016 в 20:18
14

Это повторяется и даже не совсем правильно. Вам необходимо проверить hasOwnProperty, чтобы все работало правильно.

billynoah
9 октября 2018 в 15:16
4

Изначально я проголосовал против этого на основе приведенного выше комментария, пока не понял, что этот ответ пришел первым, поэтому он не «повторяется». Возможно, он неполный, но во многих случаях работает отлично.

avatar
Richard Levasseur
26 марта 2009 в 06:04
27
for(key in p) {
  alert( p[key] );
}

Примечание: вы можете делать это с массивами, но вы также будете перебирать length и другие свойства.

Bryan
26 марта 2009 в 06:07
4

При использовании такого цикла for key будет просто принимать значение индекса, так что будет просто предупреждать 0, 1, 2 и т. Д. Вам нужно получить доступ к p [key].

Pencroff
5 декабря 2013 в 12:15
1

Это самый медленный метод итерации массива в JavaScript. Вы можете проверить это на своем компьютере - Лучший способ перебирать массивы в JavaScript

Sk8erPeter
1 января 2014 в 00:55
5

@Pencroff: проблема в том, что вопрос не в цикле по массивам ...;)

Sebastian
5 августа 2014 в 06:43
0

Этого я не понимаю на coderhelper. Ричард дал правильный ответ, и он был первым, кто дал такой ответ, но он не получил +1? @Bryan var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); } выскакивает "p1" и "p2" в предупреждениях, так что в этом плохого ???

Richard Levasseur
6 августа 2014 в 16:41
5

Я думаю, что главное отличие заключается в качестве: в других ответах говорится не только о том, как, но и о предостережениях (например, о прототипе) и о том, как с ними бороться. ИМХО, эти другие ответы лучше моих :).