(これはGitHubの私のライブラリに追加されました)
ここでホイールを再発明します!これらの解決策はどれも私の状況ではうまくいきませんでした。それで、私はすぐにwilsonpageの答えを修正しました。これは、画面に出力するためのものではありません(コンソール、テキストフィールドなど)。これらの状況では正常に機能し、OPが要求したとおりに正常に機能しalert
ます。ここでの多くの回答alert
は、要求されたOPとしての使用に対応していません。とにかく、それはデータ転送用にフォーマットされています。このバージョンはと非常に似た結果を返すようtoSource()
です。私はに対してテストしていませんJSON.stringify
が、これはほぼ同じことだと思います。このバージョンはpoly-filに似ているため、どの環境でも使用できます。この関数の結果は、有効なJavaScriptオブジェクト宣言です。
このようなものがすでにSOのどこかにあるかどうか疑いはありませんが、過去の回答を検索するのにしばらく費やすよりも、作成する方が短いだけでした。そして、私がこれについて検索し始めたとき、この質問はグーグルで私のトップヒットだったので。ここに置くと他の人の役に立つかもしれないと思った。
とにかく、オブジェクトにオブジェクトと配列が埋め込まれている場合や、オブジェクトや配列にさらにオブジェクトと配列が埋め込まれている場合でも、この関数の結果はオブジェクトの文字列表現になります。(私はあなたが飲むのが好きだと聞いた?それで、私はあなたの車をクーラーでポンピングした。それから、あなたのクーラーをクーラーでポンピングした。それであなたのクーラーはあなたが冷えている間に飲むことができる。)
配列はの[]
代わりに格納される{}
ため、キーと値のペアはありません。値のみです。通常の配列のように。したがって、配列と同じように作成されます。
また、すべての文字列(キー名を含む)は引用符で囲まれます。これらの文字列に特殊文字(スペースやスラッシュなど)がない限り、これは必要ありません。しかし、私はこれを検出する気にはなりませんでした。
この結果の文字列は、eval
文字列操作とともにvarに使用するか、そのままvarにダンプできます。したがって、テキストからオブジェクトを再作成します。
function ObjToSource(o){
if (!o) return 'null';
var k="",na=typeof(o.length)=="undefined"?1:0,str="";
for(var p in o){
if (na) k = "'"+p+ "':";
if (typeof o[p] == "string") str += k + "'" + o[p]+"',";
else if (typeof o[p] == "object") str += k + ObjToSource(o[p])+",";
else str += k + o[p] + ",";
}
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
私がそれをすべて台無しにした場合、私のテストで問題なく動作するかどうか教えてください。また、タイプを検出するために考え得る唯一の方法array
は、の存在を確認することでしたlength
。JavaScriptは配列をオブジェクトとして実際に格納するため、実際に型をチェックするarray
ことはできません(そのような型はありません!)。他の誰かがもっと良い方法を知っているなら、私はそれを聞きたいです。というのも、オブジェクトにという名前のプロパティがある場合、length
この関数は誤ってそれを配列として扱います。
編集:null値のオブジェクトのチェックが追加されました。ありがとうBrock Adams
編集:以下は、無限に再帰的なオブジェクトを印刷できるようにするための固定機能です。これはtoSource
、FFからの出力toSource
とは異なり、無限再帰を1回出力するため、この関数はすぐに強制終了します。この関数は、上記の関数よりも実行速度が遅いため、上記の関数を編集する代わりに、ここに追加します。これは、どこかにリンクしているオブジェクトを渡すことを計画している場合にのみ必要です。
const ObjToSource=(o)=> {
if (!o) return null;
let str="",na=0,k,p;
if (typeof(o) == "object") {
if (!ObjToSource.check) ObjToSource.check = new Array();
for (k=ObjToSource.check.length;na<k;na++) if (ObjToSource.check[na]==o) return '{}';
ObjToSource.check.push(o);
}
k="",na=typeof(o.length)=="undefined"?1:0;
for(p in o){
if (na) k = "'"+p+"':";
if (typeof o[p] == "string") str += k+"'"+o[p]+"',";
else if (typeof o[p] == "object") str += k+ObjToSource(o[p])+",";
else str += k+o[p]+",";
}
if (typeof(o) == "object") ObjToSource.check.pop();
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
テスト:
var test1 = new Object();
test1.foo = 1;
test1.bar = 2;
var testobject = new Object();
testobject.run = 1;
testobject.fast = null;
testobject.loop = testobject;
testobject.dup = test1;
console.log(ObjToSource(testobject));
console.log(testobject.toSource());
結果:
{'run':1,'fast':null,'loop':{},'dup':{'foo':1,'bar':2}}
({run:1, fast:null, loop:{run:1, fast:null, loop:{}, dup:{foo:1, bar:2}}, dup:{foo:1, bar:2}})
注:印刷しようとするdocument.body
と、ひどい例になります。1つは、FFはを使用するときに空のオブジェクト文字列を出力するだけtoSource
です。上記の関数を使用すると、FFがでクラッシュしSecurityError: The operation is insecure.
ます。そして、ChromeはでクラッシュしUncaught RangeError: Maximum call stack size exceeded
ます。明らかに、document.body
文字列に変換するためのものではありませんでした。大きすぎるか、セキュリティポリシーに反して特定のプロパティにアクセスできないためです。ここで何かを台無しにしない限り、教えてください!