J'ai besoin de créer une fonction qui ne peut être exécutée qu'une seule fois, à chaque fois après la première, elle ne sera pas exécutée. Je connais de C ++ et Java les variables statiques qui peuvent faire le travail mais j'aimerais savoir s'il existe une manière plus élégante de le faire?
116
Réponses:
Si par "ne sera pas exécuté" vous voulez dire "ne fera rien s'il est appelé plus d'une fois", vous pouvez créer une fermeture:
En réponse à un commentaire de @Vladloffe (maintenant supprimé): Avec une variable globale, un autre code pourrait réinitialiser la valeur de l'indicateur "exécuté" (quel que soit le nom que vous choisissez). Avec une fermeture, un autre code n'a aucun moyen de le faire, que ce soit accidentellement ou délibérément.
Comme d'autres réponses le soulignent ici, plusieurs bibliothèques (telles que Underscore et Ramda ) ont une petite fonction utilitaire (généralement nommée
once()
[*] ) qui accepte une fonction comme argument et renvoie une autre fonction qui appelle la fonction fournie exactement une fois, quelle que soit la manière dont plusieurs fois, la fonction retournée est appelée. La fonction retournée met également en cache la valeur renvoyée en premier par la fonction fournie et la renvoie lors des appels suivants.Cependant, si vous n'utilisez pas une telle bibliothèque tierce, mais que vous voulez toujours une telle fonction utilitaire (plutôt que la solution nonce que j'ai proposée ci-dessus), elle est assez facile à implémenter. La plus belle version que j'ai vue est celle publiée par David Walsh :
Je serais enclin à changer
fn = null;
pourfn = context = null;
. Il n'y a aucune raison pour que la fermeture maintienne une référence àcontext
une foisfn
a été appelée.[*] Sachez cependant que d'autres bibliothèques, telles que cette extension Drupal de jQuery , peuvent avoir une fonction nommée
once()
qui fait quelque chose de très différent.la source
if
expression de test d'instruction), JavaScript attend l'une des valeurstrue
oufalse
et le déroulement du programme réagit en fonction de la valeur trouvée lorsque l'expression est évaluée. Les opérateurs conditionnels comme==
toujours évalués à une valeur booléenne. Une variable peut également contenir soittrue
oufalse
. (Pour plus d'informations, consultez la documentation sur les booléens , les vérités et les faux .)Remplacez-le par une fonction NOOP réutilisable (sans opération) .
la source
setInterval(foo, 1000)
- et déjà cela ne fonctionne plus. Vous écrasez simplement la référence dans la portée actuelle.invalidate
Fonction réutilisable qui fonctionne avecsetInterval
etc,.: Jsbin.com/vicipar/1/edit?js,consolePointez sur une fonction vide une fois qu'elle a été appelée:
Ou, comme ça:
la source
setInterval()
) alors la référence répétera la fonctionnalité d'origine lorsqu'elle est appelée.UnderscoreJs a une fonction qui fait cela, underscorejs.org/#once
la source
once
accepter des arguments. Vous pouvez fairesquareo = _.once(square); console.log(squareo(1)); console.log(squareo(2));
et obtenir les1
deux appels àsquareo
. Suis-je bien compris?_.once
méthode. Voir jsfiddle.net/631tgc5f/1_
; Je ne recommanderais pas de dépendre de la bibliothèque entière pour un si petit morceau de code.En parlant de variables statiques, c'est un peu comme la variante de fermeture:
Vous pouvez alors réinitialiser une fonction si vous le souhaitez:
la source
la source
Vous pourriez simplement avoir la fonction "se supprimer"
Mais ce n'est peut-être pas la meilleure réponse si vous ne voulez pas avaler des erreurs.
Vous pouvez également faire ceci:
J'en ai besoin pour fonctionner comme un pointeur intelligent, s'il n'y a pas d'éléments de type A, il peut être exécuté, s'il y a un ou plusieurs éléments A, la fonction ne peut pas être exécutée.
la source
Once
est passé comme un rappel (par exemple,setInterval(Once, 100)
). La fonction d'origine continuera à être appelée.essaye ça
la source
D'un mec nommé Crockford ... :)
la source
TypeError: Cannot read property 'apply' of null
c'est génial. C'est ce que vous obtenez la deuxième fois que vous appelez la fonction renvoyée.invalidate
Fonction réutilisable qui fonctionne avecsetInterval
:Essayez-le sur JSBin: https://jsbin.com/vicipar/edit?js,console
Variation de réponse de Bunyk
la source
Voici un exemple JSFiddle - http://jsfiddle.net/6yL6t/
Et le code:
Vous pourriez faire:
Et il ne fonctionnera qu'une seule fois :)
la source
La configuration initiale:
la source
Si vous utilisez Node.js ou que vous écrivez du JavaScript avec browserify, considérez le module npm "une fois" :
la source
Si vous voulez pouvoir réutiliser la fonction à l'avenir, cela fonctionne bien sur la base du code d'ed Hopp ci-dessus (je me rends compte que la question d'origine n'appelait pas cette fonctionnalité supplémentaire!):
La sortie ressemble à:
la source
décorateur simple et facile à écrire quand vous en avez besoin
en utilisant:
la source
Essayer d'utiliser la fonction de soulignement "une fois":
http://underscorejs.org/#once
la source
la source
Si vous utilisez Ramda, vous pouvez utiliser la fonction "une fois" .
Une citation de la documentation:
la source
restez aussi simple que possible
Vous pouvez voir le résultat
la source
this
place dewindow
JQuery permet d'appeler la fonction une seule fois en utilisant la méthode one () :
Implémentation à l'aide de la méthode JQuery sur () :
Implémentation à l'aide de JS natif:
la source
la source
Celui-ci est utile pour éviter les boucles infinies (en utilisant jQuery):
Si vous vous inquiétez de la pollution de l'espace de noms, remplacez une longue chaîne aléatoire par "doIt".
la source
Cela aide à éviter une exécution collante
la source