概要
かなり昔に書かれたコード1を修正していく途中で、ふと共通関数に実装されていた「URLパラメータを取ってくれるところってどんなふうに実装してるんだろう?」と気になって見てみたら、うーん。。。って思うような実装だったので、もっとスッキリした今風な書き方は無いのか調べてみたらちゃんとあったので共有します。
元々の実装
※一部改変を入れていますがほぼ元のコード
getParam = function()
{
var paramsArray = {};
var url = location.href;
var parameters = url.split("?");
if (parameters.length == 2){
var params = parameters[1].split("&");
for ( i = 0; i < params.length; i++ ) {
var neet = params[i].split("=");
if (neet.length == 1)
paramsArray[neet[0]] = "";
if (neet.length == 2)
paramsArray[neet[0]] = neet[1];
}
}
return paramsArray;
};
URLを?
でsplitして2つに分割できたら?
以降を&
で分割して、それをさらに=
で分割して連想配列に入れていく・・・という愚直な実装
後はコーディングルール周りとして(今風な実装に書き換えるとほぼ関係ないですが)
- 変数の定義がvarを使っているレガシーな実装
- ifの中身が1行であっても
{}
使ってほしい - 細かいところで
if ( ){
とfor () {
のように条件式の)
とスコープ{
の間にスペース入れる/入れないは統一したほうがいい - neetってなんや。。。
var url = location.href;
var parameters = url.split("?");
if (parameters.length == 2){
...
の箇所はそもそもlocation.search
で取れますね。。。
元ネタ
StackOverFlowから引用させて頂いた上で補足しつつ書いていこうと思います。
今風な書き方
実装1
const urlParams = new URLSearchParams(window.location.search);
// urlParams.get('keyName') とすると値が取得できる
とりあえずシンプルでわかりやすい
詳細
URLSerchParamsを使用します。
URLSearchParams コンストラクターは完全な URL をパースしません。ただし、先頭に ? が存在すれば、読み飛ばします。
ということで、window.location.search
で取得できるクエリ文字列をそのままURLSearchParams
に渡してObjectを作れば、あとはmyParam.get(paramName)
で取得できるというわけですね。
実装2
const param = Object.fromEntries(new URLSearchParams(window.location.search));
// paramsは連想配列なので、params['keyName']やparams.keyNameで値が取得できる
連想配列化したものを返す方法
(開発者ツールでparams
を見るとさっと確認できるので個人的にはこれが好み)
詳細
#実装1と同じくURLSearchParams(window.location.search)
でObjectを作り、URLSearchParams.entries()でKey-Valのiteratorを取得
Object.fromEntries()でKey-Valのオブジェクト(連想配列)化します。
実装3
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
// params.keyName とすると値が取得できる
#実装2よりもパフォーマンス的に良いらしいけどちょっとわかりにくいかも。。。 Proxy()を知らなかったので、個人的にはわかりにくかったけど使い勝手は良さそう
ちょっと書き換えて
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop) ?? '',
});
とすると、存在しないパラメータを参照したときにnullではなく空文字が返ってくるようにできる。
詳細
Proxy でURLSearchParams
オブジェクトのgetメソッドを再定義しているので、#実装1のようにurlParams.get('keyName')
のようにせずともparams.keyName
だけで値が取得できる。
個人的には実装2がわかりやすくて好みです。
パラメータが大量にあって何度もパラメータを参照する処理があるならパフォーマンスも気にしなければなりませんが、そんなに呼び出されるわけではないので、デバッグもしやすそうな実装2へ置き換えすることにしました。
終わりに
「共通関数系は作ったら終わり!」ではなくメンテナンス大事ですね。。。
-
gitやらsvnのログを辿ったところ10年近く前が起点だったので、URLSerchParamsやObject.fromEntriesは使えなかった時代ですね。。。(IEで動くことも考えていたのかも・・・にしても元のコードは冗長的・・・) ↩