Jeśli przez „nie zostanie wykonany” masz na myśli „nic nie zrobi, gdy zostanie wywołany więcej niż raz”, możesz utworzyć zamknięcie:
var something = (function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
// do something
}
};
})();
something(); // "do something" happens
something(); // nothing happens
W odpowiedzi na komentarz @Vladloffe (teraz usunięty): W przypadku zmiennej globalnej inny kod może zresetować wartość flagi „wykonane” (niezależnie od wybranej nazwy). W przypadku zamknięcia inny kod nie może tego zrobić, ani przypadkowo, ani celowo.
Jak wskazują inne odpowiedzi, kilka bibliotek (takich jak Underscore i Ramda ) ma małą funkcję użytkową (zwykle o nazwie once()
[*] ), która przyjmuje funkcję jako argument i zwraca inną funkcję, która wywołuje podaną funkcję dokładnie raz, niezależnie od tego, jak wielokrotnie wywoływana jest funkcja zwracana. Zwracana funkcja również buforuje wartość zwróconą jako pierwsza przez podaną funkcję i zwraca ją przy kolejnych wywołaniach.
Jeśli jednak nie korzystasz z takiej biblioteki innej firmy, ale nadal chcesz mieć taką funkcję użytkową (zamiast rozwiązania jednorazowego, które zaproponowałem powyżej), jest to łatwe do wdrożenia. Najładniejsza wersja, jaką widziałem, to ta opublikowana przez Davida Walsha :
function once(fn, context) {
var result;
return function() {
if (fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
Byłbym skłonny zmienić fn = null;
się fn = context = null;
. Nie ma powodu, dla którego domknięcie zachowuje odniesienie do context
kiedyś fn
zostało wywołane.
[*] Należy jednak pamiętać, że inne biblioteki, takie jak to rozszerzenie Drupala do jQuery , mogą mieć funkcję o nazwie, once()
która robi coś zupełnie innego.