Após vermos a aplicação do conceito de JavaScript Orientado a Objetos, e Otimização de JavaScript, um outro ponto muito importante e pouco utilizado no desenvolvimento JavaScript é o carregamento dinâmico (sob demanda) das classes/arquivos.
Grandes aplicações, por motivos óbvios, acabam muitas vezes tendo grande quantidade de arquivos JavaScript para serem carregados. Uma ótima prática é carregar estes arquivos somente quando realmente necessário, sem o desenvolvedor tendo que se preocupar quando é este momento.
Vamos utilizar a classe "Carro", um pouco alterada, que foi mostrada no artigo Otimização de JavaScript, para exemplificar o carregamento dinâmico do JavaScript:
Carro.js
var Carro = function() {
var marca = "vw",
modelo = "gol",
cor = "branco";
return {
alertCor : function() {
alert(cor);
}
};
};
Carro.instance = null,
Carro.getInstance = function() {
if (!Carro.instance)
Carro.instance = new Carro();
return Carro.instance;
};Agora, vamos construir uma classe que será a única importada no código HTML (além do jQuery, que será a biblioteca JavaScript que iremos utilizar neste exemplo).
Esta classe será a responsável, sempre que necessário, pelo carregamento dos arquivos/classes JavaScript (carregamento sob demanda):
SLoader.js
var SLoader = function() {
var instanceMethod = "getInstance",
javaScriptNamePattern = "js/javaScriptName.js",
regExp = new RegExp("(.*)(javaScriptName)(.*)", "gi"),
replacementBefore = "$1",
replacementAfter = "$3",
loadScript = function(replacement) {
$.ajax({
type : "GET",
url : javaScriptNamePattern.replace(regExp, replacement),
dataType : "script",
async : false,
cache : true
});
};
return {
getObj : function(objName) {
if (eval("typeof "+ objName) != "function")
loadScript(replacementBefore + objName + replacementAfter);
return eval(objName +"."+ instanceMethod +"()");
},
newObj : function(objName) {
if (eval("typeof "+ objName) != "function")
loadScript(replacementBefore + objName + replacementAfter);
return eval("new "+ objName +"()");
}
};
};
SLoader.instance = null,
SLoader.getInstance = function() {
if (!SLoader.instance)
SLoader.instance = new SLoader();
return SLoader.instance;
},
SLoader.getObj = function(objName) {
return SLoader.getInstance().getObj(objName);
},
SLoader.newObj = function(objName) {
return SLoader.getInstance().newObj(objName);
};Atenção: Esta classe "nunca" será modificada, pois ela somente carrega os objetos requisitados dinamicamente. A única hipótese de se modificar ela, é para alterar algumas variáveis de configuração:
index.html
<html>
<head>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/SLoader.js"></script>
</head>
<body>
<a href="javascript:SLoader.getObj('Carro').alertCor();">Cor do carro</a>
</body>
</html>Veja que no código-fonte do HTML, como dito logo acima, somente teremos duas inclusões de JavaScript:
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/SLoader.js"></script>Todos os outros arquivos de classe que você for criando, serão carregados dinamicamente, sem que você tenha que alterar o arquivo SLoader.js ou o HTML de seu site.
Se você utiliza o Firebug (complemento do Firefox), perceberá que quando a página carrega, o arquivo Carro.js não está carregado. Quando se clica no link da página, automaticamente o Script Loader carrega o arquivo, instância a classe e retorna a instância para a execução do método "alertCor()".
Se seguir clicando sobre o link, o arquivo não vai ser carregado novamente, e nem ser instanciado novamente. O Script Loader consegue identificar que o arquivo já está carregado, e que a instância da classe já está criada.
Desenvolver seguindo os conceitos do JavaScript Orientado a Objetos, Otimização de JavaScript e o Carregamento dinâmico de JavaScript, exemplificado neste artigo, faz com que sua aplicação se torne robusta, padronizada, de fácil entendimento e manutenção.
Este script e aplicação foram construídos em conjunto com meu colega e amigo Henrique Oliveira.
Fernando Tessmann