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:
var something = (function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
// do something
}
};
})();
something(); // "do something" happens
something(); // nothing happens
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 :
function once(fn, context) {
var result;
return function() {
if (fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
Je serais enclin à changer fn = null;
pour fn = context = null;
. Il n'y a aucune raison pour que la fermeture maintienne une référence à context
une fois fn
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.