[JavaScript] 煩わしいURL整形処理とはおさらば！URL・クエリパラメータの操作

## はじめに
- ちょっと前クエリパラメータの整形処理を独自実装した後、**URLSearchParams**の存在を知って悲しい気持ちになりました。
- そんな人が一人でも減るように、この記事ではJavaScriptのURL操作について記載します。 :pencil: 

## URL情報について
- URL情報は大きく分けて4つに分解できます。
- URLの詳細について知りたい方はこちらの記事が参考になるかもしれません。 :rocket: 
  - [URLの基礎（初心者向けにわかりやすく解説）](https://blog.senseshare.jp/url-basic.html)
  - [URLの構造](https://www.marketechlabo.com/url-structure-for-marketer/#URL%E3%81%AE%E6%A7%8B%E9%80%A0)

```javascript
//qiitaのトレンド記事ページ
https://qiita.com/trend?type=tag
````
:one: **プロトコル**・・・通信方式の部分（`https://`（`http://`）の部分）
:two: **ホスト**・・・アクセスする対象のサーバのアドレス（場所）を表す(`qiita.com`)
:three: **パス**・・・サーバの中の場所を表す（`trend`）
:four: **クエリパラメータ**・・・サーバ側へ伝える情報（`?type=tag`）

### URL情報の取得

- それぞれの情報は **[Location](https://developer.mozilla.org/ja/docs/Web/API/Location)** インターフェースを用いて取得することができます。

|取得対象|コード|
|---|---|
|URL全体|window.location.**href**|
|プロトコル|window.location.**protocol**|
|ホスト|window.location.**hostname**|
|パス|window.location.**pathname**|
|クエリパラメータ|window.location.**search**|

### URL情報の操作
- URL情報の操作は **[URL](https://developer.mozilla.org/ja/docs/Web/API/URL)** インターフェースを使って効率的に行うことができます。

#### 情報の取得

```javascript
// window.location.href = https://qiita.com/trend?type=tag
const url = new URL(window.location.href);
// 全体
url.protocol // https://qiita.com/trend?type=tag
// プロトコル
url.protocol // https:
// ホスト
url.hostname // qiita.com
// パス
url.pathname // /trend
// クエリパラメータ
url.search  // ?type=tag
```

#### 情報の設定
- クエリパラメータの操作は次の項で紹介します。 :point_down:  

```javascript
// window.location.href = https://qiita.com/trend?type=tag
const url = new URL(window.location.href);
// ホスト
url.hostname = 'hoge.com';
// パス
url.pathname = 'huga';

console.log(url.href); //https://hoge.com/huga?type=tag
```

#### クエリパラメータの操作
- クエリパラメータの操作は[**URLSearchParams**](https://developer.mozilla.org/ja/docs/Web/API/URLSearchParams)インターフェースを使うことで効率的に行うことができます。
- ここでは代表的なメソッドをいくつか紹介します。

|メソッド|概要|
|---|---|
|**[get()](#getname)**|指定したクエリパラメータの値を**取得**（最初の1つ）する|
|**[getAll()](#getallname)**|指定したクエリパラメータの値を**全て取得**（配列）する|
|**[append()](#appendname-value)**|クエリパラメータの**追加**する|
|**[set()](#setname-value)**|指定したクエリパラメータに値を**設定**する|
|**[delete()](#deletename)**|指定したクエリパラメータを**全て削除**する|
|**[has()](#hasname)**|指定したクエリパラメータが**存在するか**を真偽値で返す|
|**[forEach()](#foreach)**|全てのクエリパラメータ対してコールバック関数を介して処理ができる|

##### get(name)
```javascript
const url = new URL('https://qiita.com/search?q=javascript&sort=stock');

url.searchParams.get('sort'); //stock
```

##### getAll(name)
```javascript
const url = new URL('https://qiita.com/search?q=javascript&sort=stock1&sort=stock2');

url.searchParams.getAll('sort'); //[stock1, stock2]
```

##### append(name, value)
```javascript
const url = new URL('https://qiita.com/search?q=javascript&sort=stock1');

url.searchParams.append('test', 100);
console.log(url.search); //?q=javascript&sort=stock1&test=100
```

##### set(name, value)
- 同一キー名が既にある場合は、その値を上書きする挙動をします。

```javascript
const url = new URL('https://qiita.com/search?q=javascript&sort=stock');

url.searchParams.set('test',100);
url.searchParams.set('sort','update');
console.log(url.search); //?q=javascript&sort=update&test=100
```

##### delete(name)
```javascript
const url = new URL('https://qiita.com/search?q=javascript&sort=stock');

url.searchParams.delete('sort');
console.log(url.search); //?q=javascript
```

##### has(name)
```javascript
const url = new URL('https://qiita.com/search?q=javascript&sort=stock');

url.searchParams.has('sort'); //true
url.searchParams.has('hogehoge'); //false
```

##### forEach()
```javascript
const url = new URL('https://qiita.com/search?q=javascript&sort=stock');

url.searchParams.forEach((value, key) => {
 console.log(key, value);
});
// q javascript
// sort stock
```
## さいごに
- 結論、クエリパラメータの操作は **URLSearchParams** を使うとスムーズです！ :sun_with_face: