Em Javascript, existem algumas técnicas claramente importantes para criar e gerenciar classes / namespaces em javascript.
Estou curioso para saber quais situações justificam o uso de uma técnica versus a outra. Eu quero escolher um e ficar com ele seguindo em frente.
Escrevo códigos corporativos que são mantidos e compartilhados entre várias equipes e quero saber qual é a melhor prática ao escrever javascript sustentável.
Eu tendem a preferir funções anônimas de auto-execução, mas estou curioso sobre o que o voto da comunidade é sobre essas técnicas.
Protótipo:
function obj()
{
}
obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();
Função anônima de fechamento automático:
//Self-Executing Anonymous Function
(function( skillet, $, undefined ) {
//Private Property
var isHot = true;
//Public Property
skillet.ingredient = "Bacon Strips";
//Public Method
skillet.fry = function() {
var oliveOil;
addItem( "\t\n Butter \n\t" );
addItem( oliveOil );
console.log( "Frying " + skillet.ingredient );
};
//Private Method
function addItem( item ) {
if ( item !== undefined ) {
console.log( "Adding " + $.trim(item) );
}
}
}( window.skillet = window.skillet || {}, jQuery ));
//Public Properties
console.log( skillet.ingredient ); //Bacon Strips
//Public Methods
skillet.fry(); //Adding Butter & Fraying Bacon Strips
//Adding a Public Property
skillet.quantity = "12"; console.log( skillet.quantity ); //12
//Adding New Functionality to the Skillet
(function( skillet, $, undefined ) {
//Private Property
var amountOfGrease = "1 Cup";
//Public Method
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
console.log( isHot ? "Hot" : "Cold" );
};
}( window.skillet = window.skillet || {}, jQuery ));
//end of skillet definition
try {
//12 Bacon Strips & 1 Cup of Grease
skillet.toString(); //Throws Exception
} catch( e ) {
console.log( e.message ); //isHot is not defined
}
Sinto que devo mencionar que a Função Anônima de Auto-Execução é o padrão usado pela equipe do jQuery.
Atualização
Quando fiz essa pergunta, não percebi a importância do que estava tentando entender. O verdadeiro problema em questão é se deve ou não usar new para criar instâncias de seus objetos ou usar padrões que não exigem construtores / uso da new
palavra - chave.
Eu adicionei minha própria resposta, porque, na minha opinião, devemos usar padrões que não usam a new
palavra - chave.
Para mais informações, consulte minha resposta.
fonte
Respostas:
Funções anônimas auto-executáveis são usadas para automatizar a execução de scripts sem conectar-se a eventos externos (por exemplo, window.onload).
Neste exemplo, ele é usado para formar o padrão clássico do Módulo, cujo objetivo principal é introduzir um espaço para nome no ambiente global e fornecer encapsulamento para quaisquer propriedades internas que não são "exportadas" ou anexadas ao espaço para nome.
A modificação de um protótipo de objetos, por outro lado, é usada para estabelecer herança (ou estender nativos). Esse padrão é usado para produzir objetos 1: n com métodos ou propriedades comuns.
Você não deve escolher um padrão em preferência ao outro, pois eles executam tarefas diferentes . Em termos de espaço para nome, a Função de Auto-Execução é uma escolha apropriada.
fonte
Aqui está o padrão que eu comecei a usar (usei variações dele até ontem):
Algumas reflexões sobre isso:
(anonymous)
rastreio nos traços da pilha do depurador, pois tudo está nomeado (sem funções anônimas).A única vez que eu usaria
prototype
mais realmente é definir herança.fonte
function clone(obj){return this typeof 'clone' ? this : new clone(clone.prototype=obj)}
prototype
método, como você sugere, é que (a menos que exista um método que eu não esteja familiarizado, que pode ser o caso), você perde a capacidade de encapsular atributos, o que significa que tudo é aberto como público (o que não é o fim do mundo). , apenas uma preferência pessoal).Uso protótipos porque são mais limpos e seguem padrões de herança padrão. As funções de auto-chamada são ótimas para o desenvolvimento do navegador ou para uma situação em que você não sabe onde o código está sendo executado, mas, caso contrário, é apenas ruído.
Exemplo:
fonte
Eu iria com a função de execução automática, mas com uma pequena diferença:
Se achar essa abordagem muito mais limpa, como eu separo a variável global retornada de qualquer parâmetro de entrada (como jQuery) (a maneira como você escreveu isso é equivalente a retornar nulo e usar um parâmetro ref em C #, o que acho um pouco errado, ou passando um ponteiro para um ponteiro e redesignando-o em C ++). Se eu fosse anexar métodos ou propriedades adicionais à classe, usaria herança prototípica (exemplo com o método $ .extend do jQuery, mas é fácil o suficiente estender sua própria extensão ()):
Dessa forma, você tem uma distinção clara entre os métodos adicionados e os métodos originais.
fonte
Exemplo ao vivo
Você pode usar um IIFE para emular o "escopo do módulo" em torno do seu código. Então você pode simplesmente usar objetos como você normalmente.
Não "emule" o estado privado usando fechamentos, pois isso tem uma grande penalidade de memória.
Se você está escrevendo um aplicativo corporativo e deseja manter o uso da memória abaixo de 1 GB, evite usar desnecessariamente fechamentos para armazenar o estado.
fonte
console
e globalconsole
é uma micro otimização. Vale a pena fazê-lo você pode minimizarconsole
, mas isso é uma questão diferenteAtualização Agora, tenho um entendimento muito melhor do javascript e sinto que posso resolver adequadamente a questão. Eu acho que foi um tópico javascript mal redigido, mas muito importante para resolver.
O padrão de função anônima de execução automática não é aquele que requer o uso da nova palavra-chave se você evitar o uso dessa função fora das funções. Concordo com a idéia de que usar o novo é uma técnica antiga e, em vez disso, devemos nos esforçar para usar padrões que evitem o uso do novo.
A função de execução automática anônima atende a esse critério.
A resposta a esta pergunta é subjetiva, porque existem muitos estilos de codificação em javascript. No entanto, com base em minha pesquisa e experiência, eu recomendaria optar por usar a função anônima auto-executável para definir suas APIs e evitar o uso de novas sempre que possível.
fonte
Aqui está como eu faria isso
IIFE
SelfExecutingFunction
para estender oMyclass
withMyclass.anotherFunction()
;fonte