location.href 代入と location.assign メソッド

発端は下記の記事を読んだから。

location.href での代入をしてページ遷移をさせるコードは良くみるが location.assign メソッドでもできるのねと。 ただ、読めば読むほどどちらも同じ機能である。どちらを使うほうが良いのだろうかと疑問がでてきた。 結論を言うと…

  • location.assign()を使う方が良さそう。

という主張に今後はなりそう。機能的には変わらない 実質的な機能に違いがあるのかと言えば「ない」と考えて良さそう。

対応ブラウザ

ほぼ全ブラウザが対応している(それはそうだ)。location.assign()の方も IE5.5 以上なので古いブラウザなどでもまったく問題なく動きそうだ。

  • location.assign(): IE5.5〜
  • location.href: Yes(なんだそりゃ)

どんな違いがあるだろうか

まずパフォーマンス的には代入(location.href)のパフォーマンスが良いという意見がある。

ただし、こちらは古い記事になる事とメモリリークが <frameset> 内で使われた場合に起きるなどかなり事象として遭遇することは少なそうだ。 またユーザー操作としてクリックなどからページ遷移をすることが多いだろうと考えられるので、ここでの両者のパフォーマンスの違いはあまりサービスの操作性などには影響がないであろう。 逆に、location.assign() の方が以下のような利点がある。

  • メソッドにすることでテストが書きやすくなる
  • 代入ではないのでコード的にもなにかアクションを起こしているように見える
  • エラーがあった場合は例外を返すようなので、その後の処理もできるかも

とくにテストを書きやすくなるのは良さそう。 また、例外としては以下のようなものが想定されているようだ

If the assignment can’t happen because of a security violation, a DOMException of the SECURITY_ERROR type is thrown. This happens if the origin of the script calling the method is different from the origin of the page originally described by the Location object, mostly when the script is hosted on a different domain. If the provided URL is not valid, a DOMException of the SYNTAX_ERROR type is thrown.

https://developer.mozilla.org/en-US/docs/Web/API/Location/assign

ドメイン内ではない遷移に関しては SECURITY_ERROR を URL に問題がある場合は SYNTAX_ERROR を返してくれるという事だ。なかなか使えそうじゃない? 今後は location.assign() 積極的に使っていこうと思う。

実際やってみた

結論、location.assign() を使った方が良いのは変わらないが、上記のように例外がとれないみたい。なので以下のように実装した。結局返り値を判断して自分で DOMException を投げている。ダサい。

try {
    if (!location.assign(link.value)) {
        throw new DOMException('不正な URL です', DOMException.DataError);
    }
} catch (error) {
    console.log(error);
    result.innerHTML = `${error.name}: ${error.message}`;
}

GitHub にもサンプルコード置いておく。うーん。もうちょっとましな書き方できそうなもんだけど…。