これはおそらく誰もが解決策を知っていると思うタスクの1つですが、多くの人が最終的にそれを間違って解決します。 この目的のために書かれたさらに別の非常に弱いコードにつまずいたので、説明的なブログ投稿を思いつきました。
問題の本質
location.hashからポンド記号
( # )を削除し
ます 。 たとえば、ハッシュが
"#foo"の場合、
"foo"を含む文字列が必要です。 簡単ですよね?
難しいケース
これは、ほとんどの開発者が見落としているように見えるものです。現代の強力にオーバースクリプトされたアプリケーションでは、
ハッシュ変数に任意のUnicode文字を含めることができます。 同じページの実際の
id 属性の値と一致する必要はありません。 そして、一致すると、
id 属性にほぼすべてのUnicode文字を含めることができるようになりました 。 さらに、彼らは多くの場合、ページにハッシュがないことを忘れます。 URLが
「#」文字で終わってい
ても、
location.hash文字列は実際には
「」では
なく 「 」 (空の文字列)です。
素朴なアプローチ
ここに最新のものがあります-私は技術的なレビューを起草した本でそれを見つけました:
var hash = location.hash.match(/#(\w+)/)[1];
彼には一度にいくつかの問題があります。
- ハッシュに非ラテン文字または非英数字文字が含まれている場合、誤った結果が返されます。 たとえば、ハッシュ「 #foo @ o#bar $%huh hello 」からは、 単に 「foo」が 取得されます 。
- location.hash行が空の場合、 TypeErrorを スローします-.match()はnullを返すためです 。
このアプローチ
には、 \ wの代わりに明示的に定義された文字クラスの使用
、「#」文字の前の文字列の先頭
( ^ )の追加(優れたアイデア、パフォーマンスに役立ちます)
、. match()メソッド
が返されるかどうかの確認など、他のオプションを見ました結果を使用する前に何でも。 ただし、それらのすべては通常、上記の2つの問題の少なくとも1つの被害者でした。
私の友人がかつて使用した別のアプローチはこれでした:
var hash = location.hash.split('#')[1];
このアプローチにも問題があります-おもしろいですが、以前のものよりも少ないですが、この方法ははるかに素朴に見えます。
- 同じテストケースでは、少なくとも
"foo@o"
が取得されます。これは、 ハッシュに記号 "#"が含まれている場合のみアプローチエラーを意味します。
- ハッシュがない場合、エラーはスローされませんが、空の文字列ではなく未定義のままになります。
正しい値を取得します。
私が通常使用する手法は、上記の2つの各手法よりもはるかに単純で、見た目が緩すぎる
場合があります。
var hash = location.hash.substring(1);
ただし、詳しく見てみましょう。
- キャッチーなテストハッシュから、正しい結果が得られます: "foo @ o#bar $%huh hello"
- ハッシュがない場合、空の文字列を正しく返します。
「しかし、彼は行の先頭に
格子があると仮定し
ます!」-あなたの一部がどのように叫ぶかを直接聞くことができます。 さて、任意の文字列を処理する場合、それは本当の懸念事項です。 次に
、「#」記号が先頭にあるかどうか、およびこの行が存在するかどうかを確認する必要があります。 ただし、
location.hashの場合
、これはハッシュがない場合だけではありません。 そして、このオプションはここで
考慮されます。
追加:コメントで
指摘されているように、
substringの代わりに
location.hash.slice(1)を使用することもできます
。 4バイト短いので、さらに気に入っています。
ただし、正規表現に夢中になっており、すべての費用をかけて彼らの助けを借りて問題を解決したい場合は、同様に防弾でほぼ同じ方法があります:
var hash = location.hash.replace(/^#/, '');
何らかの理由で(
OCD ?).
match()を
使用して問題を解決したい場合は、これを行うことができます:
var match = location.hash.match(/^#?(.*)$/)[1];
この場合、
「#」文字はオプションであるため、
.match()は決して
nullを返しません
。 いいえ、
「#」記号が誤って返されるハッシュの一部になることはありません。これが正規表現エンジンの動作方法です。
「単純すぎる、なぜここで時間を無駄にしているのか!」
まあ、ごめんなさい。 私は知っています:あなたの何人かにとってこれは初歩的です。 しかし、この本を書いた人は非常に知識が豊富です(そして、上に引用したコードを除いて、この本は本当に良いです)。だから、これは多くの優秀な開発者がこのタスクに適していないことを意味します。 あなたがそれらの1つではない場合、それを喜ぶ。
「ねえ、しかし、すべてがここにあるわけではありません!」
この場合、私が見逃したことを知りたい
ので、 コメントを
残してください
! 