JavaScriptオブジェクトのプロパティを列挙する方法を教えてください。
実際にはすべての定義済み変数とその値をリストしたいのですが、変数を定義すると実際にはウィンドウ・オブジェクトのプロパティーが作成されることがわかりました。
とても簡単
for(var propertyName in myObject) {
// propertyName is what you want
// you can get the value like this: myObject[propertyName]
}
さて、プライベート変数は利用できないので、この方法でプライベート変数を取得することはありません。
編集: @bitwiseplatypus あなたがhasOwnProperty()
メソッドを使用しない限り、あなたが継承されているプロパティを取得することは正しいです - しかし、私はなぜオブジェクト指向プログラミングに精通して誰もが期待以上になるでしょう!通常、これを引き起こす人はこれについてDouglas Crockfordの警告を受けていますが、それでも私は少し混乱します。繰り返しますが、継承はOO言語の通常の部分であり、したがってJavaScriptの原型ですが、JavaScriptの一部です。
これで、hasOwnProperty()
isはフィルタリングには便利ですが、継承されたプロパティを取得するのに危険な何かがあるかのように警告を発する必要はありません。
編集2: @bitwiseplatypus (プロトタイプを介して)最初にオブジェクトを書いたときよりも後で、誰かがあなたのオブジェクトにプロパティ/メソッドを追加した場合に起こりうる状況を思い出させます - これは事実ですが予期しない動作を引き起こす可能性がありますが、私は個人的にそれを私の問題として完全には見ていません。単なる意見です。さらに、オブジェクトの構築時にプロトタイプを使用しながら、そのオブジェクトのプロパティを反復処理するコードがあり、すべての継承プロパティを使用するように設計した場合はどうなりますか。 hasOwnProperty()
は使いません。それから、誰かが後で新しいプロパティを追加するとしましょう。物事がその時点でひどくふるまうなら、それは私のせいですか?私はそうは思わない。例として、jQueryがその動作を拡張する方法を(jQuery.extend
およびjQuery.fn.extend
を介して)指定したのはこのためだと思います。
for..in
ループを使用してオブジェクトのプロパティを列挙しますが、注意してください。列挙は、列挙されているオブジェクトのプロパティだけでなく、親オブジェクトのプロトタイプからもプロパティを返します。
var myObject = {foo: 'bar'};
for (var name in myObject) {
alert(name);
}
// results in a single alert of 'foo'
Object.prototype.baz = 'quux';
for (var name in myObject) {
alert(name);
}
// results in two alerts, one for 'foo' and one for 'baz'
継承されたプロパティが列挙に含まれないようにするには、hasOwnProperty()
を確認します。
for (var name in myObject) {
if (myObject.hasOwnProperty(name)) {
alert(name);
}
}
編集:継承されたプロパティの列挙について心配する必要がないというJasonBuntingの声明に同意しません。コードの動作を変更する可能性があるため、予期しない継承プロパティを列挙することには危険がありますis。
この問題が他の言語に存在するかどうかは関係ありません。事実、JavaScriptは特に脆弱です。オブジェクトのプロトタイプへの変更は、インスタンス化後に変更が行われた場合でも子オブジェクトに影響するためです。
これがJavaScriptがhasOwnProperty()
を提供する理由です。サードパーティのコード(またはプロトタイプを変更する可能性のある他のコード)があなたのコードを壊さないようにするためにJavaScriptを使用する必要があります。数バイトのコードを追加する以外に、hasOwnProperty()
を使用することのマイナス面はありません。
標準的な方法は、すでに何度も提案されています。
for (var name in myObject) {
alert(name);
}
ただし、Internet Explorer 6、7、および8にはJavaScriptインタプリタにバグがあり、一部のキーが列挙されないという影響があります。このコードを実行すると、
var obj = { toString: 12};
for (var name in obj) {
alert(name);
}
IE以外のすべてのブラウザで「12」と表示されます。 IEは単にこのキーを無視します。影響を受けるキー値は以下のとおりです。
isPrototypeOf
hasOwnProperty
toLocaleString
toString
valueOf
IEで本当に安全にするには、次のようなものを使用する必要があります。
for (var key in myObject) {
alert(key);
}
var shadowedKeys = [
"isPrototypeOf",
"hasOwnProperty",
"toLocaleString",
"toString",
"valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
if map.hasOwnProperty(a[i])) {
alert(a[i]);
}
}
良いニュースは、EcmaScript 5がオブジェクトのキーを配列として返すObject.keys(myObject)
関数を定義していることです。ブラウザによっては(Safari 4など)すでにそれを実装しています。
最近のブラウザ(ECMAScript 5)では、列挙可能なすべてのプロパティを取得できます。
Object.keys(obj) (古いブラウザでの下位互換性のためのスニペットを入手するにはリンクを確認してください)
あるいは、列挙不可能なプロパティも取得します。
Object.getOwnPropertyNames(obj)
追加情報: 列挙可能な属性とは何ですか?
私は驚いたことに私を捕まえた事件の例は関連があると思います:
var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
document.writeln( propertyName + " : " + myObject[propertyName] );
}
しかし驚いたことに、出力は
name : Cody
status : Surprised
forEach : function (obj, callback) {
for (prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
callback(prop);
}
}
}
どうして?ページ上の別のスクリプトがObjectプロトタイプを拡張しました。
Object.prototype.forEach = function (obj, callback) {
for ( prop in obj ) {
if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
callback( prop );
}
}
};
for (prop in obj) {
alert(prop + ' = ' + obj[prop]);
}
単純なJavaScriptコード:
for(var propertyName in myObject) {
// propertyName is what you want.
// You can get the value like this: myObject[propertyName]
}
jQuery:
jQuery.each(obj, function(key, value) {
// key is what you want.
// The value is in: value
});
for (property in object) { // do stuff }
はすべてのプロパティ、つまりウィンドウオブジェクト上でグローバルに宣言されたすべての変数を一覧表示します。
オブジェクトのプロパティを列挙する方法は次のとおりです。
var params = { name: 'myname', age: 'myage' }
for (var key in params) {
alert(key + "=" + params[key]);
}
Underscore.js ライブラリを使用している場合は、関数 keys を使用できます。
_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]
Pythonの辞書は 'キー'メソッドを持っています、そしてそれは本当に役に立ちます。 JavaScriptでは、次のようなものがあると思います。
function keys(){
var k = [];
for(var p in this) {
if(this.hasOwnProperty(p))
k.Push(p);
}
return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });
編集:しかし、@ carlos-ruanaの答えは非常にうまくいきます。私はObject.keys(window)をテストしました、そして結果は私が期待したものです。
5年後のEDIT:Object
を拡張するのは得策ではありません。オブジェクトにkeys
を使いたいと思うかもしれない他のライブラリと衝突するかもしれず、それはあなたのプロジェクトに予期しない振る舞いを引き起こすでしょう。 @ carlos-ruana答えは、オブジェクトのキーを取得するための正しい方法です。
オブジェクトに対して新しいコードを書くためにプロパティを列挙しようとしているなら、Firebugのようなデバッガを使ってそれらを視覚的に見ることをお勧めします。
もう1つの便利な方法は、PrototypeのObject.toJSON()を使用してオブジェクトをJSONにシリアル化することです。これにより、プロパティ名と値の両方が表示されます。
var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'
私はまだJavaScriptの初心者ですが、オブジェクトとその子のすべてのプロパティを再帰的に出力する小さな関数を書きました。
getDescription(object, tabs) {
var str = "{\n";
for (var x in object) {
str += Array(tabs + 2).join("\t") + x + ": ";
if (typeof object[x] === 'object' && object[x]) {
str += this.getDescription(object[x], tabs + 1);
} else {
str += object[x];
}
str += "\n";
}
str += Array(tabs + 1).join("\t") + "}";
return str;
}