JavaScript オブジェクトのすべてのプロパティ値を取得するにはどうすればよいでしょうか (キーを知らなくても)? 質問する

JavaScript オブジェクトのすべてのプロパティ値を取得するにはどうすればよいでしょうか (キーを知らなくても)? 質問する

JavaScript オブジェクトがある場合:

var objects={...};

たとえば、50 を超えるプロパティがあり、プロパティ名がわからない場合 (つまり、「キー」がわからない場合)、ループで各プロパティ値を取得するにはどうすればよいでしょうか。

ベストアンサー1

サポートするブラウザに応じて、いくつかの方法でこれを行うことができます。ほとんどのブラウザはECMAScript 5(ES5)をサポートしていますが、以下の例の多くはObject.keysIE < 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安全にしたい場合は、 を実行できます。nullfor-inObject.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 にコンパイルすると、この回答のすべての機能にアクセスできるようになります。

おすすめ記事