[Tiago Motta] Impedindo redeclaração de objetos javascript

Ao importar duas vezes um mesmo arquivo .js em uma página, as funções, protótipos e objetos são redeclarados. Se for necessário que um determinado objeto mantenha seu estado durante as iterações assíncronas dessa página, perde-se este estado na segunta importação do arquivo .js.

Veja por exemplo o objeto abaixo, que nada mais é que um repositório de outros objetos. Tá ta ta, não é um exemplo que tenha tanta utilidade, mas vá lá, é só pra explicar o mecanismo.

var Repositorio = {    sequencia:0,    lista:[],    registrar:function(obj) {        var id = ++this.sequencia;        this.lista[ id ] = obj;        return id;    },       recuperar:function(id) {        return this.lista[ id ];    }}

Agora estando esse código num arquivo por exemplo repositorio.js teríamos o problema relatado com o código a seguir:

<script src="repositorio.js"></script><script>    Repositorio.registrar( new Object() );    Repositorio.registrar( new Object() );</script><script src="repositorio.js"></script><script>    alert( Repositorio.recuperar( 1 ) );</script>

Para impedir essa redeclaração do objeto, e os possíveis erros que ela pode causar, basta tentar utilizá-lo dentro de um bloco try e fazer sua declaração dentro do bloco catch. Ou seja, ele só será declarado caso haja um erro na tentativa de usá-lo. Veja:

try{ Repositorio.existo(); }catch(e) {    Repositorio = {        sequencia:0,        lista:[],        existo:function(){},        registrar:function(obj) {            var id = ++this.sequencia;            this.lista[ id ] = obj;            return id;        },           recuperar:function(id) {            return this.lista[ id ];        }    }}

Mas aí você poderia me dizer: Pô pra que tudo isso, basta não importar duas vezes o javascript. Acontece que se você está criando uma biblioteca para ser distribuída para diversos sites e blogs, você não deve subestimar a “criatividade” dos utilizadores dela. Então, o melhor é se precaver.