Variáveis globais quase sempre são uma má ideia, mas como fugir delas em javascript ? É simples: não dá, o que podemos fazer é minimizar o número de variáveis globais.
Entendendo o problema:
O uso de variáveis globais é principal forma de trocar informações entre módulos javascript, então como usa-las sem diminuir a qualidade do código ?
Algumas maneiras de como resolver isso:
(function(){
/*private methods*/
function utils(){}
/*private variables*/
var myVar = {};
} ());
Essa abordagem é muito útil nos casos em que você não precisa de uma variável global, pois todas as funções e variáveis declaradas dentro dessa função(closure*) são de escopo privado. ? Mas e quando precisar usar/criar variáveis globais ?!
Poderia simplesmente usar um 'Anonymous Closure' para resolver esse problema ?
(function (){
jQuery(document).ready(function(){
ko.applyBindings({ });
});
} ());
É uma maneira bem simples e rápida de ganhar escopo privado, mas não, não é a melhor maneira para resolver esse problema.
==>
(function ($, ko){
$(document).ready(function(){
ko.applyBindings({});
});
} (jQuery, ko));
Importamos os modulos para nossa closure
Observem que as variáveis jQuery e ko são passadas como parametro da closure anônima.
- Performance : Em tese o interpretador vai buscar o valor da variável global em um escopo muito menor.
- Organização : O código fica muito mais claro pois fica explicito as dependências do modulo.
- Evita conflitos : Algumas bibliotecas podem usar a mesma variável:
(function($, $p){
} (jQuery, $ /*prototypejs*/));
myVar = {};
Uma variável global pode ser criada a qualquer momento simplesmente assim:
(function(){
myVar = {};
} ());
Ou mesmo dentro de uma closure anônima. Notem que deixar de usar 'var' é a mesma coisa de usar: 'window.myVar' *. (http://link)
Lembrem que a segunda forma não é a mais adequada para ganhar escopo privado.
Ao invés dela, usem :
var myApp = (function(dep){
/*private methods*/
function utils(){
return dep.returnSomething();
}
/*private variables*/
var myVar = {};
return {
/*public methods*/
init:function(){},
/*public propertys*/
version: '1.2'
};
} (DependencyLibrary));
Percebam que declarei um modulo myApp com metodo 'init' e uma propriedade 'version' e conseguimos importar um modulo externo usando-o em um metodo de escopo privado.
Proximo passo: AMD (Asynchronous Module Definition)
Dica de leitura:
Me ajudem com links para possíveis artigos em ptBr sobre:
- closure : https://developer.mozilla.org/en/JavaScript/Guide/Closures
- O uso do 'var' no javascript: https://developer.mozilla.org/en/JavaScript/Reference/Statements/var
Por enquanto é isso. Duvidas, criticas ?