Widziałem wiele razy, że fn && fn()
jest optymalizacją if (fn) fn()
."if (fn) fn()" lub "fn && fn()"
Moje pytanie brzmi: dlaczego? i jaki jest wygenerowany kod dla obu rozwiązań?
Widziałem wiele razy, że fn && fn()
jest optymalizacją if (fn) fn()
."if (fn) fn()" lub "fn && fn()"
Moje pytanie brzmi: dlaczego? i jaki jest wygenerowany kod dla obu rozwiązań?
Operator w JavaScript &&
jest zwarte, co oznacza, że jeśli lewa strona to false
, prawa strona nie jest w ogóle oceniana. Dlatego fn && fn()
jest bezpieczny, nawet jeśli fn
jest falsey (null
, undefined
itd.).
"Kod wygenerowany" będzie zależał wyłącznie od silnika JavaScript, ale spodziewam się, że będzie on bardzo podobny w obu przypadkach (&&
i if
).
To nie jest „optymalizacja” w sensie działa szybciej, ale raczej w sensie bycia krócej napisać (szczególnie jeśli tak, jak ja, nigdy zostawić {}
off if
oświadczenia). Wadą jest to, że jest on mniej oczywisty dla ludzi, którzy są nowicjuszami w tym języku, ale szybko się nauczyli.
Czy nie byłoby bezpieczniej wykonać 'typeof fn ===" function "'? – Antony
@Antony: Tak, to by było. Widzisz ten idiom w miejscach, gdzie kod spodziewa się funkcji lub nic (na przykład opcjonalny argument funkcji), a ludzie wydają się być w porządku z tym, jeśli nie powiedzie się, jeśli dasz mu coś, ale to, co mu dajesz, nie jest " t funkcja, na teorii, że dokumentacja dla funkcji (na przykład) mówi, że możesz podać funkcję lub nic, ale nie funkcję lub (powiedzmy) ciąg. :-) Ponadto niektóre funkcje hosta w niektórych silnikach mają 'typeof'' "object" '(niestety), ale nadal można je wywoływać. –
Tak więc, przez if (fn) fn()
, należy upewnić się, że fn
istnieje przed jego wykonaniem. warunek if
sprawdza wartość lub wyrażenie logiczne, w JavaScript dowolna wartość fałszerstwa może zmienić wartość na false
w warunku sprawdzania Boolean if
. Wartości Falsy mogą być:
każda inna wartość będzie wartością prawdy mi.
Tak więc, jeśli fn
jest albo null
lub undefined
wartość, sprawdzanie if
chroni przed wykonaniem przedmiotu non-funkcyjny.
Przez fn && fn()
, robisz to samo: w JavaScript, wyrażenie Boolean jest leniwe sprawdzane, co oznacza, że jeśli pierwsza część, w operacji &&
, jest falsy, to druga część nie zostanie wykonana. Dzięki tej funkcji można zabezpieczyć swój kod przed wykonaniem obiektu, który nie jest funkcją.
fn && fn()
nie jest zoptymalizowaną wersją drugiej pod względem wydajności, ale jest krótką wersją w formie pisemnej.
Oba fragmenty kodu wymagają warunku: funkcja fn
może nie być zdefiniowana lub być rzeczywistym obiektem funkcji. Jeśli w kodzie fn
ma możliwość bycia przedmiotem innych typów, takich jak łańcuch, trzeba dodać sprawdzanie typu przed wykonaniem takich jak:
if (fn instanceof Function) fn()
Pod względem optymalizacji, IMHO, powiedziałbym jej, ponieważ jest to lepszy sposób co czyni go jedną linię, jeżeli następnie, bez konieczności rezygnowania szelki i utraty czytelności, ale to nie sprawi, że kod wykonać szybciej
Co masz na myśli przez "wygenerowany kod"? – Kobi
@Kobi Zgaduję, że ma na myśli to, do czego jest skompilowany skrypt JavaScript - kod niskiego poziomu. – kba
@kobi, kba ma rację, mam na myśli kod niskiego poziomu, asembler. –