Wiem, że javascript używa pisania kaczego i na początku myślałem, że to ułatwi polimorfizm w porównaniu do silnie pisanych języków, takich jak C #. Ale teraz moje funkcje pobierające argumenty są zaśmiecone takimi rzeczami:
if(myObj.hasSomeProperty())
lub
if(myObj.hasSomeMethod())
lub
if(isNumber(myParam))
itp.
To jest dla mnie naprawdę brzydkie. Pochodzę z tła C # i uważam, że zdefiniowane interfejsy są znacznie lepsze.
Zastanawiam się, czy niepoprawnie próbuję zastosować strategie skuteczne w językach o typie statycznym i czy jest lepszy sposób na wykonanie tego w javascript?
Wiem, że po prostu nie mogłem sprawdzić, ale śledzenie błędów w czasie wykonywania javascript może być koszmarem, ponieważ nie zawsze zdarzają się tam, gdzie błąd występuje w kodzie.
javascript
polymorphism
duck-typing
Legion
źródło
źródło
Odpowiedzi:
Proste: nie zawsze sprawdzaj właściwości i metody.
W Ruby to, co nazywasz, nazywa się „pisaniem kurczaków”. W dynamicznie pisanym języku, po prostu ufasz, że osoba dzwoniąca przekazuje ci odpowiedni obiekt. Zadaniem dzwoniącego jest uhonorowanie jego strony kontraktu.
Mylisz tutaj wiele prostopadłych osi pisania. Istnieją cztery prostopadłe osie pisania:
Ponieważ wspomniałeś o C #: najczęściej jest to typowanie statyczne, ale obsługuje typowanie dynamiczne poprzez typ
dynamic
, to jest typowo typowe, ale typy anonimowe używają typowania strukturalnego, a wzorce składniowe (takie jak składnia rozumienia zapytania LINQ) mogą być argumentowane jako kaczka -typowy lub strukturalny, najczęściej jest jawnie wpisany, ale obsługuje niejawne pisanie argumentów typów ogólnych i zmiennych lokalnych (chociaż wielkość zmiennych lokalnych jest raczej dziwna w porównaniu do większości innych języków, ponieważ nie można po prostu pominąć tego typu, zamiast tego należy nadaj mu wyraźny pseudo-typvar
, innymi słowy, jeśli chcesz typ niejawny, musisz to wyraźnie powiedzieć). Jednak to, czy C # jest silnie, czy słabo typowany, zależy od tego, której definicji dwóch terminów używasz, jednak zauważ, że w C # może występować wiele błędów typu środowiska wykonawczego, szczególnie z powodu niebezpiecznej kowariancji macierzy.Debugowanie nie jest łatwą umiejętnością do nauczenia się. Istnieją jednak techniki ułatwiające debugowanie, np. Saff Squeeze to technika opisana przez Kent Beck, która używa testów i refaktoryzacji do debugowania:
źródło
IComparer<T>.Compare(T, T)
jest jasne tylko z dokumentacji, a nie typu. I gdzie w rodzajujava.util.Collections.binarySearch(java.util.List<T>)
mówi, że…Rzeczywiście, typową praktyką jest nie sprawdzanie. Tak, oznacza to, że będziesz otrzymywać błędy javascript, które są zgłaszane gdzie indziej na podstawie rzeczywistego problemu. Ale w praktyce nie uważam tego za duży problem.
Pracując w javascript, ciągle testuję to, co piszę. W większości kodów mam testy jednostkowe, które uruchamiają się automatycznie przy każdym zapisaniu mojego edytora. Kiedy coś niespodziewanie pójdzie nie tak, wiem niemal natychmiast. Mam bardzo mały obszar kodu, w którym mogłem popełnić błąd, ponieważ prawie zawsze jest to ostatnia dotykana przeze mnie pomyłka.
Kiedy pojawia się błąd czasu wykonywania, przynajmniej mam ślad stosu, aw przypadku błędu w przeglądarce mam możliwość przejścia do dowolnego poziomu śladu stosu i sprawdzenia zmiennych. Zazwyczaj łatwo jest prześledzić, skąd pochodzi zła wartość, a tym samym przywrócić pierwotny problem.
Jeśli jesteś podobny do mnie, kiedy pisałem głównie w językach o typie statycznym, pisałem większe bloki kodu przed testowaniem i nie miałem praktyki w odszukiwaniu wartości, skąd ona pochodzi. Programowanie w języku takim jak javascript jest inne, musisz używać różnych umiejętności. Podejrzewam, że takie programowanie wydaje się o wiele trudniejsze, ponieważ nie są to umiejętności, które rozwinąłeś pracując w innych językach, takich jak C #.
Powiedziawszy to, myślę, że wiele można powiedzieć o typach wyraźnych. Doskonale nadają się do dokumentacji i wczesnego wychwytywania błędów. Myślę, że w przyszłości będziemy obserwować coraz większą popularność takich rzeczy jak Flow i Typescript, które dodają statyczne sprawdzanie typu do javascript.
źródło
Myślę, że postępujesz właściwie, musisz tylko znaleźć styl, który będzie bardziej przyjemny dla oka. Oto kilka pomysłów:
Zamiast
if(myObj.hasSomeProperty())
ciebie możesz użyćif( myobj.prop !== undefined )
. To BTW będzie działać tylko w trybie ścisłym, w trybie ścisłym, którego będziesz musiał użyćif( typeof myobj.prop !== 'undefined' )
.Możesz odciąć część sprawdzania typu do osobnych walidatorów. Ma to tę zaletę, że można pominąć sprawdzanie poprawności, gdy interfejsy są dojrzałe, np.
if( is_valid( myobject ))
Gdzieis_valid
zaczyna sięif( !DEBUG ) return true;
.Czasami ma sens klonowanie danych wejściowych do postaci kanonicznej, w którym to przypadku można zebrać różne cele sprawdzania poprawności do funkcji / obiektu klonowania. Dla exmaple, w
my_data = Data( myobj, otherstuff )
tymData
konstruktora mógł wygodnie uruchomić wszystkie różne walidacje w centralnym miejscu.Możesz użyć biblioteki, która (przy opłatach za wyniki) usprawni sprawdzanie poprawności typu w coś bardziej eleganckiego. Nawet jeśli nie wybierzesz tej trasy w dłuższej perspektywie, może być dla Ciebie wygodne, abyś płynnie wprowadził Cię w swój własny styl. Niektóre przykłady obejmują xtype.js , sprawdzanie typu , validator.js itp.
źródło