Jak wykonać pętlę lub wyliczyć obiekt JavaScript?

Mam następujący obiekt JavaScript:

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

Teraz chcę przejrzeć wszystkie p Elementy (p1, p2, p3...) I zdobyć ich klucze i wartości. Jak mogę to zrobić?

W razie potrzeby mogę zmodyfikować obiekt JavaScript. Moim ostatecznym celem jest pętla przez kilka par wartości klucza i jeśli to możliwe, chcę uniknąć używania eval.

Author: Luca Kiebel, 2009-03-26

30 answers

Możesz użyć pętli for-in, Jak pokazali inni. Musisz jednak również upewnić się, że klucz, który otrzymujesz, jest rzeczywistą własnością obiektu i nie pochodzi z prototypu.

Oto fragment:

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

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}
 3589
Author: levik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 09:42:09

Pod ECMAScript 5 można połączyć Object.keys() oraz Array.prototype.forEach():

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

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

ES6 dodaje for...of:

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

ES2017 dodaje Object.entries() co pozwala uniknąć konieczności wyszukiwania każdej wartości w oryginalnym obiekcie:

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

Zarówno Object.keys() jak i Object.entries() iteracja właściwości w tej samej kolejności co pętla for...in , ale ignorowanie łańcucha prototypów . Iterowane są tylko własne właściwości wyliczeniowe obiektu.

Edit: ES2016 → ES6

 675
Author: Axel Rauschmayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 18:51:21

Musisz użyć pętli for-in

Ale bądź bardzo ostrożny przy użyciu tego rodzaju pętli, ponieważ to zapętli wszystkie właściwości wzdłuż łańcucha prototypów .

Dlatego, podczas używania pętli for-in, Zawsze używaj metody hasOwnProperty, aby określić, czy bieżąca właściwość w iteracji jest rzeczywiście właściwością obiektu, na którym sprawdzasz:

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
}
 306
Author: Andreas Grech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-24 10:51:33

Pytanie nie będzie kompletne, jeśli nie wspomnimy o alternatywnych metodach zapętlania obiektów.

Obecnie wiele znanych bibliotek JavaScript udostępnia własne metody iteracji nad kolekcjami, tj. nad tablicami , obiekty i obiekty podobne do tablicy. Metody te są wygodne w użyciu i są w pełni kompatybilne z dowolną przeglądarką.

  1. Jeśli pracujesz z jQuery , możesz użyć jQuery.each() metoda. Może być używany do bezproblemowego iterowania zarówno nad obiektami, jak i tablicami:

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. W Podkreślenie.js można znaleźć metodę _.each(), która Itera się nad listą elementów, dając każdy z kolei podanej funkcji (zwróć uwagę na kolejność argumentów w iteratee funkcji!):

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Dash dostarcza kilka metod iteracji właściwości obiektu. Podstawowe _.forEach() ( / align = "left" / _.each()) jest jednak przydatny do zapętlania zarówno obiektów, jak i tablic (!) obiekty z właściwością length są traktowane jak tablice i aby tego uniknąć, zaleca się użycie _.forIn() oraz _.forOwn() metody (te również mają argument value jako pierwsze):

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

    _.forIn() iteracje na własne i odziedziczone wyliczalne właściwości obiektu, podczas gdy _.forOwn() iteracje tylko na własne właściwości obiektu (w zasadzie sprawdzanie z hasOwnProperty funkcja). Dla prostych obiektów i literałów obiektowych każda z tych metod będzie działać poprawnie.

Ogólnie wszystkie opisane metody zachowują się tak samo z dowolnymi dostarczonymi obiektami. Poza tym używanie natywnej pętli for..in będzie zwykle szybsze niż jakakolwiek abstrakcja, taka jak jQuery.each(), Metody te są znacznie łatwiejsze w użyciu, wymagają mniej kodowania i zapewniają lepszą obsługę błędów.

 233
Author: VisioN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-08 19:43:59

W ECMAScript 5 Masz nowe podejście w polach iteracji dosłownych - Object.keys

Więcej informacji można zobaczyć na MDN

Mój wybór jest poniżej jako szybsze rozwiązanie w obecnych wersjach przeglądarek (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;
}

Możesz porównać wydajność tego podejścia z różnymi implementacjami na jsperf.com :

Wsparcie przeglądarki można zobaczyć na tabela compat Kangax

Dla starej przeglądarki masz proste i pełne polyfill

Upd:

Porównanie wydajności dla wszystkich najpopularniejszych przypadków w tym pytaniu na perfjs.info:

Iteracja obiektowa

 48
Author: Pencroff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-12 22:11:09

Można po prostu iterację nad nim jak:

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

Zauważ, że key nie przyjmie wartości właściwości, jest to tylko wartość indeksu.

 34
Author: Bryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-09 15:11:27

Ponieważ es2015 jest coraz bardziej popularny, zamieszczam tę odpowiedź, która obejmuje wykorzystanie generatora i iteratora do płynnego iteracji przez [key, value] pary. Jak to jest możliwe w innych językach np. Ruby.

Ok oto kod:

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}`);
}

Wszystkie informacje o tym, jak można wykonać iterator i generator, można znaleźć na stronie dewelopera Mozilli.

Mam nadzieję, że komuś to pomogło.

EDIT:

ES2017 będzie zawierać Object.entries, które sprawią, że iteracja ponad [key, value] pary w obiektach jeszcze łatwiejsze. Obecnie wiadomo, że będzie to część standardu zgodnie z informacją o etapie ts39.

Myślę, że nadszedł czas, aby zaktualizować moją odpowiedź, aby stała się jeszcze bardziej świeża niż teraz.

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}`);
}

Możesz znaleźć więcej o użyciu na MDN page

 24
Author: FieryCod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-30 14:34:36

Przedmowa:

  • właściwości obiektu mogą być własne (właściwość jest na samym obiekcie) lub odziedziczone (nie na samym obiekcie, na jednym z jego prototypów).
  • właściwości obiektu mogą być wyliczalne lub nie wyliczalne . Właściwości niewyliczalne są pomijane z wielu wyliczeń/tablic właściwości.
  • nazwy właściwości mogą być łańcuchami znaków lub symbolami. Właściwości, których nazwy są symbolami, są pomijane z wielu właściwości wyliczenia/tablice.

Tutaj w 2018 roku, opcje zapętlania przez właściwości obiektu są następujące:

  1. for-in [MDN, spec ] - struktura pętli, która pętli poprzez nazwy obiektów wylicza właściwości, w tym odziedziczone, których nazwy są łańcuchami
  2. Object.keys [MDN, spec ] - funkcja dostarczająca tablicę nazw własnych obiektu , wylicz właściwości, których nazwy są łańcuchami.
  3. Object.values [MDN, spec] - funkcja dostarczająca tablicę wartości własnego obiektu , enumerable właściwości.
  4. Object.entries [MDN, spec] - funkcja dostarczająca tablicę nazw i wartości własnych obiektu , enumerable właściwości.
  5. Object.getOwnPropertyNames [MDN, spec] - funkcja dostarczająca tablicę nazw własnych właściwości obiektu (nawet niewliczalnych), których nazwy są łańcuchami.
  6. Object.getOwnPropertySymbols [MDN, spec] - funkcja dostarczająca tablicę nazw własnych obiektów (nawet niewliczalnych), których nazwy są symbolami.
  7. Reflect.ownKeys [MDN, spec ] - funkcja dostarczająca tablicę nazwy własnych właściwości obiektu (nawet niewliczalne), niezależnie od tego, czy są to łańcuchy czy symbole.
  8. Jeśli chcesz wszystkich właściwości obiektu, w tym nieujemnych odziedziczonych, musisz użyć pętli i Object.getPrototypeOf [MDN, spec ] i używać Object.getOwnPropertyNames, Object.getOwnPropertySymbols, lub Reflect.ownKeys na każdym obiekcie w łańcuchu prototypów(przykład na dole tej odpowiedzi).

Z wszystkimi z wyjątkiem for-in, użyłbyś jakiegoś zapętlenia konstruuj na tablicy (for, for-of, forEach, itd.).

Przykłady:

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 (z pętlą for-of, ale można użyć dowolnej pętli construct):

// 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}`);
}

Wszystkie właściwości, W tym odziedziczone nieujemne:

// 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;
}
 18
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 10:39:33

Poprzez prototype z forEach () które powinno pominąćprototype chain właściwości:

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
 17
Author: bitstrider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-09 05:05:51

Po przejrzeniu wszystkich odpowiedzi tutaj, hasOwnProperty nie jest wymagane dla mojego własnego użytku, ponieważ mój obiekt json jest czysty; naprawdę nie ma sensu dodawać żadnego dodatkowego przetwarzania javascript. To wszystko czego używam:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
 15
Author: Francis Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-18 20:50:22
for(key in p) {
  alert( p[key] );
}

Uwaga: możesz to zrobić nad tablicami, ale będziesz iterował nad length i innymi właściwościami.

 14
Author: Richard Levasseur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-03 21:46:04

Ciekawe, że ludzie w tych odpowiedziach poruszyli zarówno Object.keys(), jak i for...of, ale nigdy ich nie połączyli:

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

nie możesz po prostu for...of an Object, ponieważ nie jest iteratorem, a for...index lub .forEach()ing Object.keys() jest brzydki/nieefektywny.
Cieszę się, że większość ludzi powstrzymuje się od for...in (z lub bez sprawdzania .hasOwnProperty()), ponieważ jest to również trochę bałagan, więc poza moją odpowiedzią powyżej, jestem tutaj, aby powiedzieć...


Można tworzyć zwykłe skojarzenia obiektów iterate! Zachowując się jak Map S z bezpośrednim wykorzystaniem fantazji for...of
DEMO pracujące w Chrome i FF (zakładam, że tylko 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);

Tak długo, jak wpiszesz mój shim poniżej:

//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;
    }};
};

Bez konieczności tworzenia prawdziwego obiektu mapy, który nie ma ładnego cukru składniowego.

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

W rzeczywistości, z tej podkładki, jeśli nadal chcesz korzystać z innych funkcji mapy (bez shimming je wszystkie w), ale nadal chcesz używać schludny obiekt notacja, ponieważ obiekty są teraz iteracyjne można teraz po prostu zrobić mapę z niego!

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

Dla tych, którzy nie lubią shim, lub bałagan z prototype w ogóle, nie krępuj się, aby funkcja w oknie zamiast, nazywając ją coś jak getObjIterator() then;

//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;
}

Teraz możesz po prostu nazwać to zwykłą funkcją, nic innego nie jest naruszone

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

Lub

for (let pair of getObjIterator(ordinaryObject))

Nie ma powodu, żeby to nie zadziałało.

Witamy w przyszłość.

 14
Author: Hashbrown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-16 03:28:59

Obiekt.keys (obj): Array

Pobiera wszystkie klucze o wartości łańcuchowej wszystkich możliwych do wyliczenia własnych (Nie dziedziczonych) właściwości.

Daje więc taką samą listę kluczy, jaką zamierzacie, testując każdy klucz obiektu za pomocą hasOwnProperty. Nie potrzebujesz tej dodatkowej operacji testowej niż i Object.keys( obj ).forEach(function( key ){}) ma być szybsza. Udowodnijmy to:

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.");

W moim Firefoksie mam następujące wyniki

  • obiekt.40.21101451665163 milisekundy.
  • for...in/hasOwnProperty podejście trwało 98.26163508463651 milisekund.

PS. na Chrome różnica jeszcze większa http://codepen.io/dsheiko/pen/JdrqXa

PS2: w ES6 (EcmaScript 2015) można iterować obiekt iteracyjny ładniejszy:

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);
});
 12
Author: Dmitry Sheiko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-22 11:33:26

Oto kolejna metoda iteracji przez obiekt.

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


Object.keys(p).forEach(key => { console.log(key, p[key]) })
 9
Author: Harsh Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-20 04:42:57

Metoda Object.keys() zwraca tablicę własnych właściwości wyliczeniowych danego obiektu. Dowiedz się więcej na ten temat TUTAJ

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

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
 8
Author: George Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-16 21:22:52

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>
 8
Author: ParaMeterz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-19 14:08:57

Możesz dodać prostą funkcję forEach do wszystkich obiektów, dzięki czemu możesz automatycznie zapętlić dowolny obiekt:

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
});

Dla tych, którzy nie lubią " dla ... w " - metoda:

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
});

Teraz możesz po prostu zadzwonić:

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

Jeśli nie chcesz mieć konfliktów z innymi metodami forEach, możesz nazwać je swoją unikalną nazwą.

 7
Author: Biber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-28 08:25:45

Tylko kod JavaScript bez zależności:

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
}
 5
Author: mohamed-ibrahim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-16 17:34:48

Pętle mogą być dość interesujące przy użyciu czystego JavaScript. Wygląda na to, że tylko ECMA6 (Nowa Specyfikacja JavaScript 2015) ma pętle pod kontrolą. Niestety, jak piszę to, zarówno przeglądarki i popularne zintegrowane środowisko programistyczne (IDE) nadal walczą o wsparcie całkowicie nowych dzwonków i gwizdków.

Oto jak wygląda pętla obiektu JavaScript przed 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;
  }
}

Poza tym, Wiem, że to jest poza zakresem tego pytania, ale w 2011 roku, ECMAScript 5.1 dodał metodę forEach tylko dla tablic, która zasadniczo stworzyła nowy, ulepszony sposób pętli przez tablice, pozostawiając obiekty nietradycyjne ze starą, gadatliwą i mylącą pętlą for. Ale dziwne jest to, że ta nowa metoda forEach nie obsługuje break, co doprowadziło do różnego rodzaju innych problemów.

Zasadniczo w 2011 roku, nie ma prawdziwego solidnego sposobu na pętlę w JavaScript poza tym, co wiele popularnych bibliotek (jQuery, Underscore, itp.) postanowił ponowne wdrożenie.

Od 2015 roku mamy teraz lepszy sposób zapętlania (i łamania) dowolnego typu obiektu (w tym tablic i łańcuchów). Oto, jak będzie wyglądać pętla w JavaScript, gdy rekomendacja stanie się głównym nurtem:

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

Zauważ, że większość przeglądarek nie będzie obsługiwać powyższego kodu od 18 czerwca 2016. Nawet w Chrome musisz włączyć tę specjalną flagę, aby działała: chrome://flags/#enable-javascript-harmony

Dopóki nie stanie się to nowym standardem, stara metoda może być nadal używana ale istnieją również alternatywy w popularnych bibliotekach lub nawet lekkich alternatyw dla tych, którzy nie używają żadnej z tych bibliotek.

 5
Author: Nicolas Bouvrette,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-18 12:55:33

Zrobiłbym to, zamiast sprawdzać obj.hasOwnerProperty w każdej pętli 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");
}
 4
Author: Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-10 10:04:59

If you want to iterate over właściwości niewyliczalne jak również, można użyć Object.getOwnPropertyNames(obj) zwraca tablicę wszystkich właściwości (możliwych do wyliczenia lub nie) znalezionych bezpośrednio na danym obiekcie.

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/>');
});
 3
Author: Dheeraj V.S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-11 05:26:12

Jeśli ktoś potrzebuje pętli przez arrayObjects z warunkiem :

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");
      }
   }
}
 3
Author: Tadas V.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-22 03:48:23

Biorąc pod uwagę ES6, chciałbym dodać własną łyżkę cukru i podać jeszcze jedno podejście do iteracji właściwości obiektu.

Ponieważ zwykły obiekt JS nie jest iterowalny po prostu wyjęty z pudełka, nie jesteśmy w stanie użyć pętli for..of do iteracji jego zawartości. Ale nikt nie może powstrzymać nas , aby uczynić go powtarzalnym.

Let ' s we have book object.

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 };
}

Skoro już to zrobiliśmy, możemy użyć tego w ten sposób:

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

Lub jeśli znasz moc ES6 Generatory , więc z pewnością możesz znacznie skrócić powyższy kod.

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

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

}

Oczywiście, można zastosować takie zachowanie dla wszystkich obiektów z dokonaniem Object iterowalnych na poziomie prototype.

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

Również obiekty zgodne z protokołem iterable mogą być używane z nowym operatorem ES2015 feature spread , dzięki czemu możemy odczytywać wartości właściwości obiektu jako tablicę.

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

Lub możesz użyć destrukcja przypisanie:

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

Możesz sprawdzić JSFiddle z całym kodem, który podałem powyżej.

 3
Author: Artyom Pranovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-02 13:56:17

W najnowszym skrypcie ES możesz zrobić coś takiego:

Object.entries(p);
 3
Author: Ankit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-11 05:55:01

    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]);
        }
    }
}
 3
Author: senthil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 17:51:00

W ES6 mamy dobrze znane symbole do ujawniania niektórych wcześniej wewnętrznych metod, można go użyć do zdefiniowania jak Iteratory działają dla tego obiektu:

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

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

Da to taki sam wynik jak przy użyciu for...in pętla es6.

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

Ale ważne jest, aby znać możliwości, które teraz masz za pomocą es6!

 2
Author: Bamieh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-20 09:04:34

Obiekt staje się iteratorem, gdy implementuje .metoda 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
 2
Author: Dan Alboteanu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-13 16:05:12

Od ES06 można uzyskać wartości obiektu jako tablicę z

let arrValues = Object.values( yourObject) ;

Zwraca tablicę wartości obiektu i nie wyciąga wartości z prototypu!!

Obiekt MDN DOCS.wartości()

And for keys (allready answerd before me here)

let arrKeys   = Object.keys(yourObject);
 2
Author: yehonatan yehezkel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 15:41:26

Jeśli chcesz iterację tylko nad właściwościami użyj jednej z powyższych odpowiedzi, jednak jeśli chcesz iterację nad wszystkim, w tym funkcjami, możesz użyć obiektu .getOwnPropertyNames (obj)

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

Czasami używam tego do szybkiego testowania wszystkich funkcji na obiektach z prostymi wejściami i wyjściami.

 1
Author: Matas Vaitkevicius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-07 11:22:18

Miałem podobny problem przy użyciu Angular, oto rozwiązanie, które znalazłem.

Punkt 1. Pobierz wszystkie klucze obiektu. korzystanie z obiektu.klucze. Metoda ta zwraca tablicę własnych właściwości wyliczeniowych danego obiektu.

Punkt 2. Utwórz pustą tablicę. To jest miejsce, gdzie wszystkie właściwości będą żyć, ponieważ nowa pętla ngFor będzie wskazywać na tę tablicę, musimy złapać je wszystkie. Krok 3. iterate wrzuć wszystkie klawisze i wciśnij każdy do tablica, którą stworzyłeś. Oto jak to wygląda w kodzie.

    // 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]);
}

Oto link do oryginalnego postu. https://medium.com/@papaponmx/looping-over-object-properties-with-ngfor-in-angular-869cd7b2ddcc

 0
Author: Jaime Rios,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-10 18:57:33