Czy podczas budowania klasy w CoffeeScript cała metoda instancji powinna być zdefiniowana za pomocą =>
operatora („gruba strzałka”), a wszystkie metody statyczne należy zdefiniować za pomocą ->
operatora?
coffeescript
arrow-functions
Ali Salehi
źródło
źródło
Odpowiedzi:
Nie, to nie jest zasada, której bym użył.
Główny przypadek użycia, jaki znalazłem dla grubej strzałki w definiowaniu metod, to sytuacja, gdy chcesz użyć metody jako wywołania zwrotnego, a ta metoda odwołuje się do pól instancji:
Jak widzisz, możesz napotkać problemy z przekazaniem odwołania do metody instancji jako wywołania zwrotnego, jeśli nie używasz fat-arrow. Dzieje się tak, ponieważ gruba strzałka wiąże wystąpienie obiektu,
this
podczas gdy cienka strzałka nie, więc metody cienkiej strzałki wywoływane jako wywołania zwrotne, jak powyżej, nie mogą uzyskać dostępu do pól instancji, takich jak@msg
inne metody instancji. W ostatnim wierszu znajduje się obejście dla przypadków, w których została użyta cienka strzałka.źródło
this
, co zostanie wywołane z cienkiej strzałki, ale także zmiennych instancji, które otrzymałeś za pomocą grubej strzałki?this
ustawiony na zmienną, której chcę użyć. Jednak chcę również odwołać się do metody klasy, więc chcęthis
również odwołać się do klasy. Mogę wybrać tylko jedno przypisanie dlathis
, więc jaki jest najlepszy sposób, aby móc używać obu zmiennych?Kwestią niewymienioną w innych odpowiedziach, o której należy pamiętać, jest to, że wiązanie funkcji grubą strzałką, gdy nie jest to konieczne, może prowadzić do niezamierzonych wyników, takich jak w tym przykładzie z klasą, którą po prostu nazwiemy DummyClass.
W tym przypadku funkcje robią dokładnie to, czego można się spodziewać i wydaje się, że użycie grubej strzałki nie przynosi żadnych strat, ale co się dzieje, gdy modyfikujemy prototyp DummyClass po jego już zdefiniowaniu (np. Zmiana jakiegoś alertu lub zmiana wyjścia dziennika) :
Jak widzimy, nadpisanie naszej wcześniej zdefiniowanej funkcji prototypu powoduje poprawne nadpisanie funkcji some_function, ale funkcja other_function pozostaje taka sama w instancjach, ponieważ gruba strzałka spowodowała powiązanie funkcji other_function z klasy ze wszystkimi instancjami, więc instancje nie będą odwoływać się z powrotem do swojej klasy znaleźć funkcję
Nawet gruba strzałka nie będzie działać, ponieważ gruba strzałka powoduje jedynie powiązanie funkcji z nowymi instancjami (które zyskują nowe funkcje zgodnie z oczekiwaniami).
Prowadzi to jednak do pewnych problemów, co jeśli potrzebujemy funkcji (np. W przypadku przełączania funkcji logowania do pola wyjściowego lub czegoś podobnego), która będzie działać na wszystkich istniejących instancjach (w tym obsłudze zdarzeń) [jako takiej nie możemy użyć grube strzałki w oryginalnej definicji], ale nadal potrzebujemy dostępu do atrybutów wewnętrznych w module obsługi zdarzeń [dokładny powód, dla którego użyliśmy grubych strzał, a nie cienkich strzał].
Cóż, najprostszym sposobem osiągnięcia tego jest po prostu włączenie dwóch funkcji do oryginalnej definicji klasy, jednej zdefiniowanej cienką strzałką, która wykonuje operacje, które chcesz wykonać, a drugiej zdefiniowanej grubą strzałką, która nie robi nic poza wywołaniem pierwszej funkcji na przykład:
Więc kiedy używać cienkich / grubych strzał, można podsumować dość łatwo na cztery sposoby:
Funkcje samej cienkiej strzałki powinny być używane, gdy spełnione są oba warunki:
Funkcji samej strzałki tłuszczu należy używać, gdy spełniony jest następujący warunek:
Funkcja grubej strzałki, która bezpośrednio wywołuje funkcję cienkiej strzałki, powinna być używana, gdy spełnione są następujące warunki:
Funkcja cienkiej strzałki, która bezpośrednio wywołuje funkcję grubej strzałki (nie pokazano), powinna być używana, gdy spełnione są następujące warunki:
We wszystkich podejściach należy wziąć pod uwagę w przypadku, gdy funkcje prototypu mogą zostać zmienione, czy zachowanie dla określonych instancji będzie zachowywać się poprawnie, na przykład mimo że funkcja jest zdefiniowana grubą strzałką, jej zachowanie może nie być spójne w instancji, jeśli wywołuje metoda, która została zmieniona w prototypie
źródło
Zwykle
->
jest w porządku.Zwróć uwagę, jak metoda statyczna zwraca obiekt klasy dla,
this
a instancja zwraca obiekt instancji dlathis
.Dzieje się tak, że składnia wywołania dostarcza wartości
this
. W tym kodzie:foo
będziebar()
domyślnie kontekstem funkcji. Więc to po prostu działa tak, jak chcesz. Gruba strzałka jest potrzebna tylko wtedy, gdy wywołujesz te funkcje w inny sposób, który nie używa składni kropki do wywołania.W obu tych przypadkach użycie grubej strzałki do zadeklarowania, że funkcja pozwoli im działać. Ale jeśli nie robisz czegoś dziwnego, zwykle nie musisz.
Więc używaj,
->
dopóki naprawdę nie potrzebujesz=>
i nigdy nie używaj=>
domyślnie.źródło
x = obj.instance; alert x() == obj # false!
=>
byłoby potrzebne w metodach statycznych / instancji klasy.// is not a CoffeeScript comment
podczas gdy# is a CoffeeScript comment
.setTimeout foo.bar, 1000
„robi źle”? Używanie grubej strzały jest znacznie przyjemniejsze niż używaniesetTimeout (-> foo.bar()), 1000
IMHO.setTimeout
. Ale twój pierwszy komentarz jest nieco wymyślony i nie ujawnia uzasadnionego przypadku użycia, ale po prostu ujawnia, jak może się zepsuć. Po prostu mówię, że nie należy używać a,=>
chyba że jest to potrzebne z dobrego powodu, szczególnie w przypadku metod instancji klas, w których wiąże się to z kosztem wydajności związanym z utworzeniem nowej funkcji, która musi być związana z instancją.tylko przykład zrozumienia grubej strzały
nie działa: (@canvas undefined)
prace: (zdefiniowano @canvas)
źródło