Preciso criar uma função que possa ser executada apenas uma vez, em cada vez após a primeira não será executada. Eu sei de C ++ e Java sobre variáveis estáticas que podem fazer o trabalho, mas gostaria de saber se existe uma maneira mais elegante de fazer isso.
javascript
function
design-patterns
vlio20
fonte
fonte
Respostas:
Se por "não será executado" você quiser dizer "não fará nada quando for chamado mais de uma vez", você pode criar um encerramento:
Em resposta a um comentário de @Vladloffe (agora excluído): Com uma variável global, outro código poderia redefinir o valor do sinalizador "executado" (qualquer nome que você escolher para ele). Com um encerramento, outro código não tem como fazer isso, seja acidental ou deliberadamente.
Como outras respostas aqui apontam, várias bibliotecas (como Underscore e Ramda ) têm uma pequena função de utilidade (normalmente chamada
once()
[*] ) que aceita uma função como um argumento e retorna outra função que chama a função fornecida exatamente uma vez, independentemente de como muitas vezes a função retornada é chamada. A função retornada também armazena em cache o primeiro valor retornado pela função fornecida e o retorna nas chamadas subsequentes.No entanto, se você não estiver usando essa biblioteca de terceiros, mas ainda quiser essa função de utilitário (em vez da solução nonce que ofereci acima), é fácil de implementar. A versão mais legal que vi é esta postada por David Walsh :
Eu estaria inclinado a mudar
fn = null;
parafn = context = null;
. Não há razão para o fechamento manter uma referência acontext
uma vezfn
que foi chamado.[*] Esteja ciente, entretanto, que outras bibliotecas, como esta extensão do Drupal para jQuery , podem ter uma função chamada
once()
que faz algo bastante diferente.fonte
if
expressão de teste de instrução), o JavaScript espera um dos valorestrue
oufalse
e o fluxo do programa reage de acordo com o valor encontrado quando a expressão é avaliada. Operadores condicionais como==
sempre avaliam um valor booleano. Uma variável também pode contertrue
oufalse
. (Para mais informações, consulte a documentação on boolean , truthy e Falsey .)Substitua-o por uma função NOOP (sem operação) reutilizável .
fonte
setInterval(foo, 1000)
- e isso já não funciona mais. Você está apenas substituindo a referência no escopo atual.invalidate
Função reutilizável que funciona comsetInterval
etc.: Jsbin.com/vicipar/1/edit?js,consoleAponte para uma função vazia depois de chamada:
Ou, assim:
fonte
setInterval()
), a referência repetirá a funcionalidade original quando chamada.UnderscoreJs tem uma função que faz isso, underscorejs.org/#once
fonte
once
aceitar argumentos. Você poderia fazersquareo = _.once(square); console.log(squareo(1)); console.log(squareo(2));
e receber1
para ambas as chamadas parasquareo
. Estou entendendo isso direito?_.once
método. Consulte jsfiddle.net/631tgc5f/1_
; Eu não recomendaria depender de toda a biblioteca para um pequeno trecho de código.Falando sobre variáveis estáticas, isso é um pouco como a variante de encerramento:
Você pode redefinir uma função se desejar:
fonte
fonte
Você poderia simplesmente ter a função "remover a si mesmo"
Mas essa pode não ser a melhor resposta se você não quiser engolir erros.
Você também pode fazer isso:
Preciso que funcione como smart pointer, se não houver elementos do tipo A ele pode ser executado, se houver um ou mais elementos A a função não poderá ser executada.
fonte
Once
for passado como um retorno de chamada (por exemplo,setInterval(Once, 100)
). A função original continuará a ser chamada.tente isso
fonte
De um cara chamado Crockford ... :)
fonte
TypeError: Cannot read property 'apply' of null
é ótimo. Isso é o que você obtém na segunda vez que invoca a função retornada.invalidate
Função reutilizável que funciona comsetInterval
:Experimente no JSBin: https://jsbin.com/vicipar/edit?js,console
Variação de resposta de Bunyk
fonte
Aqui está um exemplo de JSFiddle - http://jsfiddle.net/6yL6t/
E o código:
Você poderia fazer:
E será executado apenas uma vez :)
fonte
Configuração inicial:
fonte
Se você usa Node.js ou escreve JavaScript com browserify, considere o módulo npm "uma vez" :
fonte
Se você quiser reutilizar a função no futuro, isso funciona bem com base no código de ed Hopp acima (percebi que a pergunta original não exigia esse recurso extra!):
A saída é semelhante a:
fonte
decorador simples e fácil de escrever quando você precisa
usando:
fonte
Tentando usar a função de sublinhado "uma vez":
http://underscorejs.org/#once
fonte
fonte
Se estiver usando Ramda, você pode usar a função "uma vez" .
Uma citação da documentação:
fonte
mantenha-o o mais simples possível
Você pode ver o resultado
fonte
this
vez dewindow
JQuery permite chamar a função apenas uma vez usando o método one () :
Implementação usando o método JQuery em () :
Implementação usando JS nativo:
fonte
fonte
Este é útil para prevenir loops infinitos (usando jQuery):
Se você está preocupado com a poluição do namespace, substitua "doIt" por uma string longa e aleatória.
fonte
Ajuda a prevenir a execução pegajosa
fonte