JavaScript オブジェクトがある場合:
var objects={...};
たとえば、50 を超えるプロパティがあり、プロパティ名がわからない場合 (つまり、「キー」がわからない場合)、ループで各プロパティ値を取得するにはどうすればよいでしょうか。
ベストアンサー1
サポートするブラウザに応じて、いくつかの方法でこれを行うことができます。ほとんどのブラウザはECMAScript 5(ES5)をサポートしていますが、以下の例の多くはObject.keys
IE < 9では利用できないを使用していることに注意してください。互換性表。
ECMAScript 3以上
古いバージョンの IE をサポートする必要がある場合は、次のオプションを選択してください。
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var val = obj[key];
// use val
}
}
ネストによりif
、オブジェクトのプロトタイプチェーン内のプロパティを列挙することがなくなります(これはほぼ確実に必要な動作です)。
Object.prototype.hasOwnProperty.call(obj, key) // ok
それよりも
obj.hasOwnProperty(key) // bad
ECMAScript 5+ では、 を使用してプロトタイプのないオブジェクトを作成できるためObject.create(null)
、これらのオブジェクトには メソッドがありませんhasOwnProperty
。不適切なコードによって、 メソッドをオーバーライドするオブジェクトが生成される可能性もありますhasOwnProperty
。
ECMAScript 5以上
これらのメソッドは、ECMAScript 5 以降をサポートする任意のブラウザで使用できます。これらはオブジェクトから値を取得し、プロトタイプ チェーンを列挙することを回避します。obj
オブジェクトはどこにありますか:
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var val = obj[keys[i]];
// use val
}
もう少しコンパクトなものが必要な場合、またはループ内の関数に注意したい場合は、Array.prototype.forEach
次のコードが役に立ちます。
Object.keys(obj).forEach(function (key) {
var val = obj[key];
// use val
});
次のメソッドは、オブジェクトの値を含む配列を構築します。これはループするのに便利です。
var vals = Object.keys(obj).map(function (key) {
return obj[key];
});
// use vals array
を使用しているものを(現状のまま)Object.keys
安全にしたい場合は、 を実行できます。null
for-in
Object.keys(obj || {})...
Object.keys
は列挙可能なプロパティを返します。単純なオブジェクトを反復処理する場合、通常はこれで十分です。列挙不可能なプロパティを持つオブジェクトを処理する必要がある場合は、Object.getOwnPropertyNames
の代わりにを使用できますObject.keys
。
ECMAScript 2015+ (別名 ES6)
ECMAScript 2015 では、配列の反復処理が簡単になりました。ループ内で値を 1 つずつ操作するときに、これを活用できます。
for (const key of Object.keys(obj)) {
const val = obj[key];
// use val
}
ECMAScript 2015 のファットアロー関数を使用すると、オブジェクトを値の配列にマッピングすることが 1 行で済みます。
const vals = Object.keys(obj).map(key => obj[key]);
// use vals array
ECMAScript 2015 では が導入されSymbol
、そのインスタンスはプロパティ名として使用できます。列挙するオブジェクトのシンボルを取得するには、 を使用しますObject.getOwnPropertySymbols
(この関数が、をプライベート プロパティの作成に使用Symbol
できないReflect
理由です)。ECMAScript 2015 の新しいAPI は を提供しReflect.ownKeys
、これはプロパティ名 (列挙できないものも含む) とシンボルのリストを返します。
配列の内包表記(使用しないでください)
配列の内包表記は、 ECMAScript 6 の公開前に削除されました。削除される前の解決策は次のようになります。
const vals = [for (key of Object.keys(obj)) obj[key]];
// use vals array
ECMAScript 2017+
ECMAScript 2016 では、この主題に影響しない機能が追加されました。ECMAScript 2017 仕様では、Object.values
およびが追加されましたObject.entries
。どちらも配列を返します (との類似性を考えると、驚く人もいるでしょうArray.entries
)。Object.values
は、そのまま使用することも、for-of
ループと一緒に使用することもできます。
const values = Object.values(obj);
// use values array or:
for (const val of Object.values(obj)) {
// use val
}
キーと値の両方を使用する場合は、Object.entries
が最適です。ペアで満たされた配列を生成します[key, value]
。これをそのまま使用することも、(ECMAScript 2015 の分割代入にも注意してください) ループで使用することもできますfor-of
。
for (const [key, val] of Object.entries(obj)) {
// use key and val
}
Object.values
シム
最後に、コメントや別の回答の teh_senaus が指摘しているように、これらのいずれかをシムとして使用する価値があるかもしれません。心配しないでください。次のコードはプロトタイプを変更するものではなく、メソッドを追加するだけですObject
(危険性ははるかに低くなります)。ファットアロー関数を使用すると、これも 1 行で実行できます。
Object.values = obj => Object.keys(obj).map(key => obj[key]);
これを次のように使用できます
// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });
ネイティブがObject.values
存在する場合にシミングを回避したい場合は、次のようにします。
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
ついに...
サポートする必要があるブラウザ/バージョンに注意してください。上記は、メソッドまたは言語機能が実装されている場合に当てはまります。たとえば、ECMAScript 2015のサポートは、最近までV8ではデフォルトでオフになっていましたが、Chromeなどのブラウザではこれが採用されていました。サポートする予定のブラウザが必要な機能を実装するまで、ECMAScript 2015の機能は避けるべきです。バベルコードを ECMAScript 5 にコンパイルすると、この回答のすべての機能にアクセスできるようになります。