Premissas
Com base na pergunta, acredito que algumas suposições / requisitos para esta função incluem:
- Ele será usado como uma função de biblioteca e, portanto, deve ser descartado em qualquer base de código;
- Como tal, ele precisará trabalhar em muitos ambientes diferentes , ou seja, trabalhar com código JS legado, CMSes de vários níveis de qualidade, etc .;
- Para interoperar com o código escrito por outras pessoas e / ou código que você não controla, a função não deve fazer suposições sobre como os nomes ou valores dos cookies são codificados . Chamar a função com uma string
"foo:bar[0]"deve retornar um cookie (literalmente) chamado "foo: bar [0]";
- Novos cookies podem ser escritos e / ou cookies existentes modificados a qualquer momento durante a vida útil da página.
Sob essas premissas, fica claro que encodeURIComponent/ decodeURIComponent não deve ser usado ; isso pressupõe que o código que definiu o cookie também o codificou usando essas funções.
A abordagem da expressão regular fica problemática se o nome do cookie puder conter caracteres especiais. O jQuery.cookie soluciona esse problema codificando o nome do cookie (na verdade, nome e valor) ao armazenar um cookie e decodificando o nome ao recuperar um cookie. Uma solução de expressão regular está abaixo.
A menos que você esteja apenas lendo os cookies que controla completamente, também seria aconselhável ler os cookies document.cookiediretamente e não armazenar em cache os resultados, pois não há como saber se o cache é inválido sem a leitura document.cookienovamente.
(Embora o acesso e a análise document.cookiessejam um pouco mais lentos que o uso de um cache, não seria tão lento quanto a leitura de outras partes do DOM, pois os cookies não desempenham um papel nas árvores de renderização / DOM.)
Função baseada em loop
Aqui está a resposta do Code Golf, com base na função do PPK (baseada em loop):
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, '');
}
que quando compactado, possui 128 caracteres (sem contar o nome da função):
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,'');}
Função baseada em expressão regular
Atualização: se você realmente deseja uma solução de expressão regular:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
Isso evita qualquer caractere especial no nome do cookie antes de construir o objeto RegExp. Minificado, trata-se de 134 caracteres (sem contar o nome da função):
function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}
Como Rudu e cwolves apontaram nos comentários, a expressão regular de escape de expressão regular pode ser reduzida por alguns caracteres. Eu acho que seria bom manter o regex de escape consistente (você pode usá-lo em outro lugar), mas vale a pena considerar suas sugestões.
Notas
Ambas as funções não tratam nullou undefined, ou seja, se houver um cookie chamado "null", readCookie(null)retornará seu valor. Se você precisar lidar com esse caso, adapte o código adequadamente.