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.cookie
diretamente e não armazenar em cache os resultados, pois não há como saber se o cache é inválido sem a leitura document.cookie
novamente.
(Embora o acesso e a análise document.cookies
sejam 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 null
ou 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.