JavaScript で, 華麗に URL パラメーターを取得してオブジェクトに変換する方法
9 years ago
昨日, JavaScriptでURLパラメーターを取得し配列に格納しておく - Qiita というエントリーがバズってて, 自分も似たような機能をよく自作するので紹介したいと思います.
タイトルはちょっと盛っちゃってますが, 見る人によっては 気持の良い実装コードになっていると思います.
Code
QueryString
というオブジェクトに対して, parse
, stringify
をそれぞれ定義しています.
var QueryString = {
parse: function(text, sep, eq, isDecode) {
text = text || location.search.substr(1);
sep = sep || '&';
eq = eq || '=';
var decode = (isDecode) ? decodeURIComponent : function(a) { return a; };
return text.split(sep).reduce(function(obj, v) {
var pair = v.split(eq);
obj[pair[0]] = decode(pair[1]);
return obj;
}, {});
},
stringify: function(value, sep, eq, isEncode) {
sep = sep || '&';
eq = eq || '=';
var encode = (isEncode) ? encodeURIComponent : function(a) { return a; };
return Object.keys(value).map(function(key) {
return key + eq + encode(value[key]);
}).join(sep);
},
};
parse
の方は, reduce
の第二引数にオブジェクトを渡すってとこが肝ですね.
isDecode
と isEncode
は, false
のとき空関数が呼ばれるので無駄にオーバーヘッドかかっちゃいますが,
ループ内で何度も判定するのはナンセンスだし, if ~ else
で分岐して同じようなコードを書くのも微妙だなと思い, コードの美しさを優先した次第です.
QueryString.parse
解説です. コード中にコメント書きまくってます.
parse: function(text, sep, eq, isDecode) {
// デフォルト値を設定
text = text || location.search.substr(1); // 省略時は URL パラメータ
sep = sep || '&'; // 省略時は &
eq = eq || '='; // 省略時は =
// デコードするかどうか
var decode = (isDecode) ? decodeURIComponent : function(a) { return a; };
// sep(&) で split した配列を reduce で回した結果を返す
return text.split(sep).reduce(function(obj, v) {
// eq(=) で split して一番目を key 二番目を value として obj に代入
var pair = v.split(eq);
obj[pair[0]] = decode(pair[1]);
return obj;
}, {});
},
Examples
普通に使う
QueryString.parse('hoge=100&foo=bar'); // {"hoge":"100", "foo":"bar"}
引数省略時は location.search.substr(1)
がパース対象となる
// http://hoge.com?foo=100&bar=bon だった場合
QueryString.parse(); // {"foo":"100", "bar":"bon"}
& と = 以外の文字も指定できる(第2と第3引数)
QueryString.parse('2*4|4*2', '|', '*'); // {"2":"4","4":"2"}
decode するかどうかも指定可能(第4引数)
QueryString.parse('名前=%E3%83%95%E3%82%A1%E3%82%A4', null, null, true); // {"名前":"ファイ"}
QueryString.stringify を実装しよう
解説です. parse と同じくコード中にコメント書きまくってます.
stringify: function(value, sep, eq, isEncode) {
// デフォルト値を設定
sep = sep || '&'; // 省略時は &
eq = eq || '='; // 省略時は =
// エンコードするかどうか
var encode = (isEncode) ? encodeURIComponent : function(a) { return a; };
// Object.keys で key 配列を取得し, それを map で回した結果を sep(&) で join して返す
return Object.keys(value).map(function(key) {
// key, value を eq(=) で連結した文字列を返す
return key + eq + encode(value[key]);
}).join(sep);
},
Examples
普通に使う
QueryString.stringify({"hoge":"100", "foo":"bar"})
& と = 以外の文字も指定できる(第2と第3引数)
QueryString.stringify({"2":"4","4":"2"}, '|', '*'); // 2*4|4*2
encode するかどうかも指定可能(第4引数)
QueryString.stringify({"名前":"ファイ"}, null, null, true); // 名前=%E3%83%95%E3%82%A1%E3%82%A4
Demo
上記で紹介した実装と実例の実行サンプルです. 実際にイジって遊んでみてください♪