次のようなJavaScriptオブジェクトがあります。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
今度はすべてのp
要素(p1
、p2
、p3
...)をループ処理し、それらのキーと値を取得します。どうやってやるの?
必要に応じてJavaScriptオブジェクトを修正することができます。私の最終的な目標は、いくつかのキーと値のペアをループ処理することであり、可能であればeval
の使用は避けたいと思います。
他の人が示すようにfor-in
ループを使うことができます。ただし、取得したキーが実際のオブジェクトのプロパティであり、プロトタイプから来ていないことも確認する必要があります。
スニペットは次のとおりです。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}
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)
);
Object.keys()
とObject.entries()
はどちらもfor...in
ループ と同じ順序でプロパティを繰り返しますが、プロトタイプチェーン は無視します。オブジェクト自身の列挙可能なプロパティだけが繰り返されます。
あなたはfor-in loopを使う必要があります
ただし、このようなループを使用する場合は注意が必要です。これはプロトタイプチェーンに沿ってすべてのプロパティをループするになるためです。
したがって、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
}
オブジェクトをループ処理するための代替方法について言及していなければ、問題は完全ではありません。
今日では、多くの有名なJavaScriptライブラリーがコレクションを反復するための独自のメソッドを提供しています。すなわち、array、objects、およびarray-like objects)です。これらのメソッドは使いやすく、完全に互換性があります。任意のブラウザ.
jQuery を使用する場合は、 jQuery.each()
メソッドを使用できます。オブジェクトと配列の両方をシームレスに繰り返すために使用できます。
$.each(obj, function(key, value) {
console.log(key, value);
});
Underscore.js では、 _.each()
というメソッドを見つけることができます。これは、要素のリストを反復し、それぞれを提供された関数に変換します(iterateeの引数の順序に注意します)。関数!):
_.each(obj, function(value, key) {
console.log(key, value);
});
Lo-Dash は、オブジェクトプロパティを反復処理するためのいくつかのメソッドを提供します。基本的な _.forEach()
(またはその別名_.each()
)は、オブジェクトと配列の両方をループ処理するのに役立ちますが、(!)length
プロパティを持つオブジェクトは配列のように扱われるため、 _.forIn()
を使用することをお勧めします。そして _.forOwn()
メソッド(これらもvalue
引数を最初に持っています):
_.forIn(obj, function(value, key) {
console.log(key, value);
});
_.forIn()
はオブジェクトの独自の、継承された列挙可能なプロパティに対して繰り返しますが、_.forOwn()
はオブジェクトの独自のプロパティに対してのみ繰り返します。基本的にhasOwnProperty
関数に対してチェックします。)大丈夫です。
一般に、記述されているすべてのメソッドは、提供されているオブジェクトと同じ動作をします。ネイティブのfor..in
ループを使うことは通常jQuery.each()
のようなどんな抽象化よりも速いになります)、これらのメソッドはかなり使いやすく、必要なコーディングが少なく、より良いエラー処理を提供します。
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のcompat tableで見ることができるブラウザサポート
古いブラウザでは simple と full polyfillがあります。
UPD:
perfjs.info
に関するこの質問の中で最も人気のあるすべてのケースのパフォーマンス比較:
次のようにそれを繰り返すことができます。
for (var key in p) {
alert(p[key]);
}
key
はプロパティの値をとらず、単にインデックス値です。
序文:
ここ2018年では、オブジェクトのプロパティをループするためのあなたのオプションは次のとおりです。
for-in
[ _ mdn _ 、 spec ] - オブジェクトのenumerableプロパティの名前をループ処理するループ構造。名前は文字列です。Object.keys
[ _ mdn _ 、 spec ] - 名前が文字列であるオブジェクトのown、enumerableプロパティの名前の配列を提供する関数。Object.values
[ _ mdn _ 、 spec ] - オブジェクトのown、enumerableプロパティのvaluesの配列を提供する関数。Object.entries
[ _ mdn _ 、 spec ] - オブジェクトのown、enumerableの名前との値の配列を提供する関数]プロパティ。Object.getOwnPropertyNames
[ _ mdn _ 、 spec ] - オブジェクトのownプロパティの名前(列挙できないものであっても)の名前の配列を提供する関数文字列.Object.getOwnPropertySymbols
[ _ mdn _ 、 spec ] - オブジェクトのownプロパティの名前(列挙できないものであっても)の名前の配列を提供する関数シンボル.Reflect.ownKeys
[ _ mdn _ 、 spec ] - オブジェクトのownプロパティの名前の配列(列挙できないものも含む)を提供する関数名前は文字列またはシンボルです。Object.getPrototypeOf
[ _ mdn _ / spec ]を使用し、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;
}
Es2015がますます普及しているので、私はこの答えを投稿しています。これには[key, value]
のペアをスムーズに繰り返すためのgeneratorとiteratorの使い方が含まれます。 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ページにあります。
それが誰かを助けたことを願っています。
編集:
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 _ ページにあります。
prototype with forEach() を使用すると、 プロトタイプチェーンをスキップする必要があります properties:
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
ここですべての答えを調べた後、私のjsonオブジェクトはクリーンなので、hasOwnPropertyは私の使用には必要ありません。 JavaScript処理を追加しても意味がありません。私が使っているのはこれだけです。
for (var key in p) {
console.log(key + ' => ' + p[key]);
// key is key
// value is p[key]
}
for(key in p) {
alert( p[key] );
}
注:これは配列に対しても実行できますが、length
および他のプロパティに対しても反復します。
これらの回答に興味を持った人は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()
するのは醜い/非効率的です。
ほとんどの人が(.hasOwnProperty()
をチェックしてもしなくても)for...in
を差し控えているのが嬉しいです。
通常のオブジェクトの関連付けを繰り返すことができます。空想for...of
を直接使用しているMap
sのように振る舞う
_ 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;
}};
};
Nice構文糖を持たない実際の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
をめちゃくちゃにしたくない人は、代わりにwindowで関数を作成してください。その場合は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))
未来へようこそ。
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では、次のような結果が出ました。
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);
});
これは、オブジェクトを反復処理するもう1つの方法です。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach(key => { console.log(key, p[key]) })
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>
Object.keys()
メソッドは、与えられたオブジェクト自身の列挙可能なプロパティの配列を返します。それについてもっと読む ここ
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
単純な 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
});
" for ... in " - メソッドが気に入らない人のために:
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-Methodsと競合したくない場合は、一意の名前で名前を付けることができます。
純粋なJavaScriptを使用する場合、ループは非常に興味深いものになる可能性があります。 ECMA6(New 2015 JavaScript specification)のみがループを制御下に置いたようです。残念ながら、これを書いている時点では、ブラウザと一般的な統合開発環境(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
ループを残しながら配列を通してループする新しい改良された方法を作成するArrays onlyのfor
メソッドを追加しました。しかし奇妙なことに、この新しいforEach
メソッドはbreak
をサポートしていないため、他のさまざまな問題が発生します。
基本的に2011年には、多くの一般的なライブラリ(jQuery、Underscoreなど)が再実装することを決めた以外には、JavaScriptをループするための本当の確かな方法はありません。
2015年現在、任意のオブジェクトタイプ(配列と文字列を含む)をループ(および分割)するためのすぐれた方法があります。推奨事項が主流になったときに、JavaScriptのループが最終的にどのようになるかを次に示します。
for (let [key, value] of Object.entries(object)) {
console.log(key); // This is the key;
console.log(value); // This is the value;
}
2016年6月18日現在、ほとんどのブラウザで上記のコードがサポートされていないことに注意してください。Chromeでは、この特別なフラグを有効にする必要があります。chrome://flags/#enable-javascript-harmony
これが新しい標準になるまでは、古い方法を使用することができますが、一般的なライブラリには代替手段、あるいはこれらのライブラリを使用していない人のための lightweight alternatives もあります。
依存関係のない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
}
すべての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");
}
Object.keys()を使用して、以下のようにオブジェクトキーを反復処理して値を取得することもできます。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach((key)=> {
console.log(key +' -> '+ p[key]);
});
ES6を考えて、私は自分の砂糖のスプーンを追加し、オブジェクトのプロパティを反復するためのもう1つのアプローチを提供したいと思います。
プレーンな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機能 spread 演算子と共に使用できます。したがって、オブジェクトプロパティ値を配列として読み取ることができます。
let pValues = [...book];
console.log(pValues);
-------------------------
["Amazing book", "Me", 3]
あるいは、 destructuring assignmentを使用することもできます。
let [title, , pages] = book; // notice that we can just skip unnecessary values
console.log(title);
console.log(pages);
------------------
Amazing book
3
上で提供したすべてのコードで JSFiddle をチェックアウトできます。
誰かが 配列オブジェクトを条件 でループする必要がある場合
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");
}
}
}
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]);
}
}
}
最新のESスクリプトでは、次のようなことができます。
Object.entries(p);
列挙不可能なプロパティを繰り返し処理する場合は、 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/>');
});
eS06以降では、オブジェクトの値を配列として取得できます。
let arrValues = Object.values( yourObject) ;
オブジェクト値の配列を返し、Prototypeから値を抽出しません。
そしてキーのために(すでにここで私の前に答えた)
let arrKeys = Object.keys(yourObject);
ES6では、以前の内部メソッドを公開するためのよく知られたシンボルがあります。これを使用して、このオブジェクトに対するイテレータの動作方法を定義できます。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3",
*[Symbol.iterator]() {
yield *Object.keys(this);
}
};
[...p] //["p1", "p2", "p3"]
これは、es6ループでfor ...を使用した場合と同じ結果になります。
for(var key in p) {
console.log(key);
}
しかし、es6を使用している機能を知っておくことは重要です。
オブジェクトが.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
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);
}
プロパティだけを反復したい場合は上記の答えの1つを使いますが、関数を含むすべてを反復したい場合は Object.getOwnPropertyNames(obj) を使います。
for (let o of Object.getOwnPropertyNames(Math)) {
console.log(o);
}
私は時々これを単純な入力と出力を持つオブジェクト上のすべての関数を高速にテストするために使用します。
Angularを使用しているときにも同様の問題がありました。これが私が見つけた解決策です。
Step 1.すべてのオブジェクトキーを取得します。 Object.keysを使用します。このメソッドは、指定されたオブジェクト自身の列挙可能なプロパティの配列を返します。
Step 2.空の配列を作成します。あなたの新しいngForループがこの配列を指すようになるので、これがすべてのプロパティが有効になるところです。 Step 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
アプリケーションが文字列作成の場合、Niceの組み合わせはObject.keys、implode、および.map配列メソッドです。たとえば、次のようなjsonオブジェクトがあるとします。
var data = {
key1: 10,
key2: 'someString',
key3: 3000
}
「そして値はkey1 = 10、key2 = someString、key3 = 3000です。」と生成します。
これを1行のコードで実行できます。
var str = `The values are ${implode(', ', Object.keys(data).map(function(key){return `${key} = ${data[key]}`}))}.`;
Implodeは、要素間に挿入された区切り文字(最初の引数)を使用して配列を文字列に縮小します。 .mapは、配列を返す配列を繰り返し処理し、Object.keysは他の答えによって非常にうまく作成されています。
これは、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>