jshash – Implementando um Hash em JavaScript
Recentemente escrevi algum código javascript que realizava algumas requisições, e a fim de não buscar informações redundantes, armazenava um cache desses dados que chegavam. Simplificadamente, algo como:
var cache = {}; function buscaEProcessaDados(id){ var dados; if(!cache[id]){ // faz a requisição e retorna dados cache[id] = dados; } // Processa }
E estava funcionando tudo bem. Mas pensando bem, isso não está muito seguro. Vamos supor que outro script na página execute o seguinte código:
Object.prototype.foo = function(){alert('te peguei!')};
e eu quisesse buscar algum dado que tenha id = foo.
buscaEProcessaDados('foo'); // :(
Mesmo não havendo nenhum dado armazenado na propriedade 'foo' daquele objeto cache que foi criado vazio mais acima, o teste
!!cache[id] //-> true
será interpretado como true, já que o JavaScript encontrará essa propriedade ao subir a cadeia de prototypes (escreverei sobre isso em breve) em busca de algo com nome 'foo'.
A maneira que encontrei para resolver este problema foi implementar um hash simples, com métodos de put, get e remove. O objeto que conterá as propriedades fica inacessível para código fora do objeto construído e as chaves são concatenadas a uma string gerada a partir do timestamp no momento da instanciação.
function Hash(){ var _hash = {}; var pre = '__' + (new Date()).getTime() + '__'; function put(key, value){ _hash[pre + key] = value; return this; } function get(key){ return _hash[pre + key]; } function remove(key){ delete _hash[pre + key]; } return { 'put': put, 'get': get, 'remove': remove } }
Utilizando o Hash, nosso código anterior fica assim:
var cache = new Hash(); function buscaEProcessaDados(id){ var dados, cached = cache.get(id); if(!cached){ // faz a requisição e retorna dados cache.put(id, dados); } // Processa }
e mesmo que a propriedade 'foo' esteja sendo herdada do Object.prototype, podemos ficar seguros que ela não interferirá em nossa hash:
typeof cache.foo == 'function' && typeof cache.get('foo') == 'undefined'; //-> true
É claro que esta Hash é bem primitiva e muitos métodos ainda podem ser implementados. Ainda assim ela funciona perfeitamente para propósitos simples como o demonstrado acima.
Como de costume, o código está hospedado no GitHub, e o download pode ser feito aqui.
Tags: hash, javascript




