JSON.stringifyの第2引数を使って出力結果(JSON)を整形する
JSON.stringify() メソッドは値を JSON に変換します。置き換え関数を指定して値を置き換えたり、置き換え配列を指定して指定されたプロパティのみを含むようにしたりします。
JavaScriptで値をJSONに変換するのにとても便利なメソッドですが、細かい使い方をしらなかったので調べてみました。
インデントを指定する
stringifyメソッドは三つの引数を受け取りますが、3番目の引数に空白文字を指定することで出力結果のインデントを付加することができます。
わりとよく使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
var a = {"number":100, "string":"hoge", "date":new Date, "array":[10,20,30], "object":{"hellow": "world"}, "function":function(){ alert("test") } }; JSON.stringify(a); -> '{"number":100,"string":"hoge","date":"2014-10-08T02:04:02.416Z","array":[10,20,30],"object":{"hellow":"world"}}' //タブでインデント JSON.stringify(a, null , "\t"); -> '{ "number": 100, "string": "hoge", "date": "2014-10-08T02:04:02.416Z", "array": [ 10, 20, 30 ], "object": { "hellow": "world" } }' |
ちなみにstringifyメソッドではfunctionは出力されません。
replacerを使う
今回のメイン。ほとんど使ったことがありません。
stringifyメソッドの2番目の引数にはreplacerと呼ばれるコールバックを指定できます。replacerにはキーと値が引数として受け渡されるので、それらを使って出力されるJSONを整形することができます。
下記は、dateの値をmoment.jsを使って整形しJSONとして出力しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
var a = {"number":100, "string":"hoge", "date":new Date, "array":[10,20,30], "object":{"hellow": "world"}, "function":function(){ alert("test") } }; var res = JSON.stringify(a, function(key, val){ if (key === "date") { return moment(new Date(val)).format('YYYY/MM/DD h:mm:ss'); } return val; }, "\t"); console.log(res); -> '{ "number": 100, "string": "hoge", "date": "2014/10/08 11:14:21", //整形された値 "array": [ 10, 20, 30 ], "object": { "hellow": "world" } }' |
……ぶっちゃけ、あまり使いどころがない気がします。
ちなみにreplacerの中でnullやundefinedを返すとstringifyメソッドの戻り値はundefinedになってしまうので、値を削ったり削除したりするのには使えません。
個人的にこういう用途不明な機能が大好きなので、なんか面白い使い方ができないか研究中です。
余談
stringifyメソッドはオブジェクト内にfunctionがあってもJSONとして出力しませんが、上記replacerを使って文字列に変換することで出力することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
var a = {"number":100, "string":"hoge", "date":new Date, "array":[10,20,30], "object":{"hellow": "world"}, "function":function(){ alert("test") } }; var res = JSON.stringify(a, function(key, val){ if (typeof val === "function") { return val.toString(); } return val; }, "\t"); console.log(res); -> \"{ "number": 100, "string": "hoge", "date": "2014-10-08T02:24:40.354Z", "array": [ 10, 20, 30 ], "object": { "hellow": "world" }, "function": "function (){ alert(\"test\") }" }\" |
でも、関数をjsonで渡すのはセキュリティ的に問題があるのでやめましょう。