概要
HistoryAPIを使う必要があったため、replaceStateメソッドのドキュメントを見ていたら以下のような構文が書かれていました。
replaceState(state, unused)
replaceState(state, unused, url)
第2引数を見てみるとunused
と書かれています。なんだこれは・・・。
引数の説明には以下のように書かれていました。
この引数は歴史的な理由のために存在しており、省略することはできません。空文字を渡すことが、将来このメソッドに変更が加えられたときに安全です。
どうやら元々使う予定だった引数だったが、何かしらの理由で利用されなくなってしまったようです。
「歴史的な理由」という言葉にがぜん好奇心がそそられたため、少し調べてみることにしました。
replaceStateの第2引数は何者か?
まず第2引数にはもともと何が渡される想定だったのかを見ていきましょう。
mdnの以下ドキュメントに記載がありました。
(以下はpushStateの説明です。pushStateもreplaceState同様、第2引数はunusedとなっています)
title
Safari 以外のすべてのブラウザーは、現在この引数を無視しています。ただし、将来的には使用する可能性があります。ここで空文字列を渡せば、将来このメソッドが変更されても安全です。あるいは、移動先の状態を表す短いタイトルを渡すこともできます。
これをみる限りだと第2引数にはtitleという引数が渡される想定だったようです。
第2引数に文字列を渡すことで、履歴の追加・更新と併せてページのタイトルを指定した文字列に変更することができたようです。
なぜ第2引数titleは使われなくなったのか?
引数の説明を見る限りだとSafari以外のブラウザはtitleに引数が渡されていたとしても無視しているようです。
そのためtitleが使われなくなったのは 「各ブラウザベンダーが不要な機能だと判断したから」 であると言えます。
ではなぜブラウザベンダー達は、titleを不要な機能だと判断したのか?
これについては関連する情報が見つけられず真相はわからず仕舞いでした。(もしご存知の方がいたら教えて頂きたいです)
代わりと言ってはなんですがGPT-4の回答を貼っておきます。
個人的には3つ目の理由がしっくりきていて、「普通にdocument.title
で変更できるんだからpushState
やreplaceState
の引数でtitleを変える必要は無いよね」となったのではないかと推測しています。
まとめ
pushState
やreplaceState
の第2引数がunused
とされている理由について調査してみました。
「unused
として空文字列を渡すくらいなら第2引数を無くせばいいじゃん」とも思いましたが、Safariでは機能するようなので既に使用しているユーザーのことを考えた結果、今の仕様に落ち着いたという感じなのかもしれません。
HTML5の仕様に携わった方のインタビューでもpushState
に関しては以下のように語られていました。
実際に運用してみなきゃ善し悪しが分からないのに、運用後の仕様変更は難しいという点はある種の開発者共通のジレンマかもしれませんね・・・。
パブリックに開発され多くの人にレビューされた機能であっても、実際にはそのプロセスが終わる前に実装され使われ始めてしまう。そしていったん使われ始めると、それは変更できなくなってしまう。これが出来の悪いAPIにつながってしまうのだ。例えばpushState()みたいな。引数が要求されているのに無視されてしまう。
難しいのは、仕様の善し悪しは現実世界のWebで実装してみなければ分からないのに、その実装によるテストが適切に行われたあとではもう仕様を変更するには遅すぎる、という点だ。pushState()に起きたのはこういうことだ。