以下の JavaScript コードの実行結果として正しいものはどれですか? const url = new URL('/api/users', 'https://example.com:8080'); url.searchParams.set('role', 'admin'); url.searchParams.set('active', 'true'); console.log(url.href);
解説
new URL(path, base) は第2引数の base URL を基準に、第1引数の相対パスを解決して完全な URL オブジェクトを生成します。今回は base が 'https://example.com:8080' なので、ポート番号 8080 がそのまま保持されます。選択肢Aはポート番号が欠落しているため不正解です。選択肢Cは相対パスのまま出力されていますが、href プロパティは常にスキームから始まる完全な URL 文字列を返します。選択肢Dについては、第1引数が相対パスでも第2引数に有効な base URL があれば正常に動作するため、エラーにはなりません。new URL が TypeError を投げるケースURL コンストラクタは渡された文字列が有効な URL として解釈できない場合に TypeError をスローします。具体的には以下のパターンです。第1引数が相対パスなのに第2引数(base)を省略した場合: new URL('/api/users')第1引数・第2引数ともに不正な文字列の場合: new URL('not-a-url', 'also-not-a-url')逆に、第1引数が 'https://...' のように完全な URL であれば、第2引数は無視されます。この仕様を利用して、「渡された文字列が有効な URL かどうか」のバリデーションに使う手法もあります。function isValidURL(str) { try { new URL(str); return true; } catch { return false; } }文字列結合ではなく URL オブジェクトを使う理由URL にクエリパラメータを付けるとき、テンプレートリテラルで `/api?role=${role}` のように組み立てるコードをよく見かけます。しかしこの方法では、値に & や = や日本語が含まれる場合にエンコード漏れが起きます。searchParams.set() を使えば自動的にパーセントエンコーディングが適用されるため、手動で encodeURIComponent() を呼ぶ必要がありません。const url = new URL('https://example.com/search'); url.searchParams.set('q', 'TypeScript 入門'); console.log(url.href); // https://example.com/search?q=TypeScript+%E5%85%A5%E9%96%80また、searchParams は URLSearchParams のインスタンスなので、append()(同名キーを複数追加)、delete()、has()、toString() などのメソッドも利用できます。実務では API クライアントのリクエスト URL 組み立てやリダイレクト先の構築で多用するため、文字列結合の代わりに URL オブジェクトを使う習慣をつけると、エンコード起因のバグを防げます。