仮定
質問に基づいて、私はこの機能のいくつかの仮定/要件が含まれていると信じています:
- これはライブラリー関数として使用されるため、任意のコードベースにドロップすることを意図しています。
- そのため、レガシーJSコード、さまざまなレベルの品質のCMSなど、さまざまな環境で動作する必要があります。
- 他の人が記述したコードやユーザーが制御していないコードと相互運用するには、関数でCookieの名前や値のエンコード方法を想定しないでください。文字列を指定して関数を呼び出すと、
"foo:bar[0]"
「foo:bar [0]」という名前のCookie(文字通り)が返されます。
- ページの存続期間中いつでも、新しいCookieを書き込んだり、既存のCookieを変更したりできます。
これらの仮定の下では、encodeURIComponent
/ decodeURIComponent
を使用すべきでないことは明らかです。これを行うには、Cookieを設定するコードが、これらの関数を使用してCookieもエンコードすると想定しています。
Cookie名に特殊文字を含めることができる場合、正規表現のアプローチは問題になります。jQuery.cookieは、Cookieを保存するときにCookie名(実際には名前と値の両方)をエンコードし、Cookieを取得するときに名前をデコードすることにより、この問題を回避します。正規表現の解決策は次のとおりです。
完全に制御するCookieのみを読み取る場合を除き、キャッシュを無効にするかどうかを再度読み取ることなく知ることができないため、結果をキャッシュせずにCookieをdocument.cookie
直接読み取ることをお勧めしますdocument.cookie
。
(アクセスと解析document.cookies
はキャッシュを使用するよりも少し遅くなりますが、CookieはDOM /レンダーツリーで役割を果たさないため、DOMの他の部分を読み取るほど遅くはありません。)
ループベースの機能
PPKの(ループベースの)関数に基づいたコードゴルフの答えを次に示します。
function readCookie(name) {
name += '=';
for (var ca = document.cookie.split(/;\s*/), i = ca.length - 1; i >= 0; i--)
if (!ca[i].indexOf(name))
return ca[i].replace(name, '');
}
これを縮小すると、128文字になります(関数名は含まれません)。
function readCookie(n){n+='=';for(var a=document.cookie.split(/;\s*/),i=a.length-1;i>=0;i--)if(!a[i].indexOf(n))return a[i].replace(n,'');}
正規表現ベースの関数
更新:正規表現ソリューションが本当に必要な場合:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
これにより、RegExpオブジェクトを作成する前に、Cookie名の特殊文字がエスケープされます。縮小すると、これは134文字になります(関数名は含まれません)。
function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}
Ruduとcwolvesがコメントで指摘したように、正規表現をエスケープする正規表現を数文字短くすることができます。エスケープする正規表現の一貫性を保つことは良いことだと思います(他の場所で使用している可能性があります)が、それらの提案は検討に値します。
ノート
これらの関数はどちらもnull
orを処理しませんundefined
。つまり、「null」という名前のcookieがある場合、readCookie(null)
その値を返します。このケースを処理する必要がある場合は、それに応じてコードを調整してください。