web-dev-qa-db-ja.com

Javascriptオブジェクトのすべてのプロパティ値を(キーを知らなくても)取得する方法は?

Javascriptオブジェクトがある場合

var objects={...};

ループ内の各プロパティ値を取得する方法(プロパティの名前がわからない)(つまり、「キー」がわからない)、50を超えるプロパティがあるとします。

424
Mellon

単純なfor..inループを使うことによって:

for(var key in objects) {
    var value = objects[key];
}
415
Tatu Ulmanen

サポートする必要があるブラウザーに応じて、これはいくつかの方法で実行できます。圧倒的多数のブラウザはECMAScript 5(ES5)をサポートしていますが、以下の例の多くはIE <9では利用できないObject.keysを使用していることに注意してください 互換性テーブル

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は、enumerableプロパティを返します。単純なオブジェクトを反復処理するには、通常これで十分です。処理する必要がある列挙不可能なプロパティを持つものがある場合は、Object.getOwnPropertyNamesの代わりにObject.keysを使用できます。

ECMAScript 2015+(A.K.A. ES6)

配列は、ECMAScript 2015を使用して簡単に反復できます。ループで値を1つずつ操作する場合、これを使用して利点を得ることができます。

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}

ECMAScript 2015のファットアロー関数を使用して、オブジェクトを値の配列にマッピングすると、ワンライナーになります。

const vals = Object.keys(obj).map(key => obj[key]);

// use vals array

ECMAScript 2015にはSymbolが導入されており、そのインスタンスはプロパティ名として使用できます。列挙するオブジェクトのシンボルを取得するには、Object.getOwnPropertySymbolsを使用します(この関数がSymbolを使用してプライベートプロパティを作成できない)。 ECMAScript 2015の新しいReflect AP​​IはReflect.ownKeysを提供し、プロパティ名(列挙不可能なものを含む)とシンボルのリストを返します。

配列内包表記(使用しようとしないでください)

配列内包表記は、公開前にECMAScript 6からremovedでした。削除する前のソリューションは次のようになりました。

const vals = [for (key of Object.keys(obj)) obj[key]];

// use vals array

ECMAScript 2017+

ECMAScript 2016は、この主題に影響を与えない機能を追加します。 ECMAScript 2017仕様では、Object.valuesObject.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で述べられているように、これらの1つをシムとして使用する価値があるかもしれません。心配する必要はありません。以下はプロトタイプを変更せず、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]));

最後に...

サポートする必要があるブラウザ/バージョンに注意してください。メソッドまたは言語機能が実装されている場合、上記は正しいです。たとえば、V8ではECMAScript 2015のサポートが最近までデフォルトでオフになっており、Chromeなどのブラウザーに電力を供給していました。サポートするブラウザが必要な機能を実装するまで、ECMAScript 2015の機能は使用しないでください。 babel を使用してコードをECMAScript 5にコンパイルすると、この回答のすべての機能にアクセスできます。

972
qubyte

これは、値を配列に入れるための再利用可能な関数です。プロトタイプも考慮に入れます。

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.Push(obj[key]);
        }
    }
    return vals;
}
30
teh_senaus

Underscore.jsにアクセスできる場合は、 _.values 関数を次のように使用できます。

_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
28
jichi

本当に値の配列が必要な場合は、for ... inループを使用して配列を作成するよりもこの方法のほうがきれいです。

ECMA 5.1以降

function values(o) { return Object.keys(o).map(function(k){return o[k]}) }

注目すべきは、ほとんどの場合、実際には値の配列が必要ではないことです。これを実行するほうが速いでしょう。

for(var k in o) something(o[k]);

これはObject oのキーを繰り返し処理します。各反復で、kはoのキーに設定されます。

14
zzz

ES5 Object.keys

var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
8
MrBii

キーをループすることができます。

foo = {one:1, two:2, three:3};
for (key in foo){
    console.log("foo["+ key +"]="+ foo[key]);
}

出力されます:

foo[one]=1
foo[two]=2
foo[three]=3
5
ariera

次のようなポリフィルを使用します。

if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}

それから使う

Object.values(my_object)

3)利益!

3
user40521

CofeeScript時代に初期の人たちが慣れ親しんでいる人のために、これに相当するものがもう1つあります。

val for key,val of objects

これはobjectsが再び入力されるように減らされて読みやすさを減少させることができるのでこれより良いかもしれません。

objects[key] for key of objects
3
Ch.Idea

どうやら - 私が最近学んだように - これはそれをするための最速の方法です:

var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
    // do whatever in here
    var obj = objs[objKeys[i]];
}
2
dylnmc

ECMA2017以降:

Object.values(obj)はすべてのプロパティ値を配列として取得します。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

2
ishandutta2007

Object.values()を使用します。オブジェクトを引数として渡し、値の配列を戻り値として受け取ります。

これは与えられたオブジェクト自身の列挙可能なプロパティ値の配列を返します。 for inループを使用した場合と同じ値が得られますが、Prototypeのプロパティはありません。この例はおそらく物事をより明確にするでしょう:

function person (name) {
  this.name = name;
}

person.prototype.age = 5;

let dude = new person('dude');

for(let prop in dude) {
  console.log(dude[prop]);     // for in still shows age because this is on the prototype
}                              // we can use hasOwnProperty but this is not very elegant

// ES6 + 
console.log(Object.values(dude));
// very concise and we don't show props on prototype
1

私は少し遅れていることを実感しますが、これが新しいFirefoxのObject.valuesメソッドの shim です

Object.prototype.values = Object.prototype.values || function(obj) {
  return this.keys(obj).map(function(key){
    return obj[key];
  });
};
0
Jamie

Object.entriesはより良い方法でそれを行います。

  var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
 
   Object.entries(dataObject).map(itemArray => { 
     console.log("key=", itemArray[0], "value=", itemArray[1])
  })
0
Must Keem J

これはPHPのarray_values()に似た関数です。

function array_values(input) {
  var output = [], key = '';
  for ( key in input ) { output[output.length] = input[key]; }
  return output;
}

ES6以上を使用している場合にオブジェクトの値を取得する方法は次のとおりです。

Array.from(values(obj));
0
jaggedsoft

ES7と互換性がありますが、まだサポートしていないブラウザもあります。

以来、Object.values(<object>)ES7&に組み込まれます。

すべてのブラウザがそれをサポートするのを待つまでは、関数の中にラップすることができます。

Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])

その後:

Object.vals({lastname:'T',firstname:'A'})
 // ['T','A']

ブラウザがES7と互換性を持つようになれば、コードの内容を変更する必要はなくなります。

0
Abdennour TOUMI