【JavaScript】オブジェクトのプロパティ一覧をブラウザで表示する
更新日:2023/04/24
ふと、JavaScriptでオブジェクトのプロパティと値の一覧をテーブルタグを使ってブラウザ表示してみようと思いました。
動的な結果をブラウザ表示するとき、個々の値を変更することが多いです。
しかしオブジェクトにセットして一括で変更できたら、少し手間が省けるかもしれません。
オブジェクトのプロパティを取得する
プロパティ名の取得はObject.keys()やfor...in構文がありますが、これらは列挙可能属性がtrueのもののみ取得できます。
今回は列挙不可のものも取得したいので、別の方法を利用します。
次のような関数を他のページで作成しているので、それを使用します。
// obj .. 対象のオブジェクト
// ignoreObjectProto .. Objectオブジェクトを除外するかどうか
const getForInAllPropertys = (obj,ignoreObjectProto=true)=>{
const loopCheck = new WeakSet(); // ループ回避用
const propNames = new Set(); // プロパティ名セット用
const isObjectProto = ignoreObjectProto
? ( proto )=> proto === Object.prototype
: ()=>false;
do{
loopCheck.add( obj );
Object.getOwnPropertyNames(obj).forEach( e=>propNames.add( e ) );
obj = Object.getPrototypeOf( obj );
}while( obj !== null && !isObjectProto(obj) && !loopCheck.has( obj ));
return [...propNames];
};
上のコードについてはリンク先で解説しているので、読んでみてください。
この関数を使ってclass構文で生成したオブジェクトのプロパティ名を取得してみます。
const B = class{
propB = [1,2,3];
u8Array = new Uint8Array(10);
funcb(){};
};
const A = class extends B{
propA = "A";
setA = new Set([1,2,3]);
funcA(){};
};
const a = new A();
console.log( getForInAllPropertys( a ) );
// 結果: [ "propB", "u8Array", "funcb", "propA", "setA", "constructor", "funcA" ]
ちなみに、for...in構文は次のような結果になります。
const result = [];
for( const value in a ){
result.push( value );
}
console.log( result );
// 結果: [ "propB", "u8Array", "propA", "setA" ]
class構文のメソッドは列挙不可になるので、for...inで取得できません。
意外と面倒ですね…class構文って。
tableタグを出力する
プロパティ名を取得できたら、その値を使ってtableを作成します。
const getObjectTable = obj =>{
const propNames = getForInAllPropertys( obj );
return "<table><tr><th>プロパティ名</th><th>値</th></tr>"
+ propNames.map( e=>`<tr><td>${e}</td><td>${getValueString(obj[e])}</td></tr>`).join("\n")
+ "</table>";
};
getValueString()は他ページで紹介した関数で、値をブラウザのコンソール出力にような形式で文字列化します。
次のようなコードです。
const getValueString = value =>{
if( value === undefined ) return "undefined";
if( value === null ) return "null";
const type = typeof value;
switch(type){
case "string": return "\"" + value + "\"";
case "bigint": return value.toString() + "n";
case "object":
return `${ getObjectName(value) } ${
isIterable( value )
? "[" + [...value].toString() + "]"
: JSON.stringify(value)
}`;
}
return value.toString();
}
const isIterable = obj =>
typeof obj !== "object" || obj === null
? false
: typeof obj[Symbol.iterator] ==="function";
// オブジェクトを生成したコンストラクターの名前を取得
const getObjectName = obj =>{
if( typeof obj !=="object" ) return typeof obj;
const proto = Object.getPrototypeOf(obj);
return typeof proto?.constructor !== "function" || proto.constructor.name === undefined
? "object" : proto.constructor.name;
};
動作の確認をしてみます。
getObjectTable()の結果を、div要素等にセットします。
document.getElementById( "id" ).innerHTML = getObjectTable(a);
実行すると、次のようなテーブルが生成されました。
プロパティ名 | 値 |
---|---|
propB | Array [1,2,3] |
u8Array | Uint8Array [0,0,0,0,0,0,0,0,0,0] |
propA | "A" |
setA | Set [1,2,3] |
constructor | class extends B{ propA = "A"; setA = new Set([1,2,3]); funcA(){}; } |
funcA | funcA(){} |
funcb | funcb(){} |
想定したとおりに完成したので、満足です。
更新日:2023/04/24
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。