Dlaczego JavaScript nie jest używany do klasycznego tworzenia aplikacji (skompilowane oprogramowanie)? [Zamknięte]

14

Podczas moich lat tworzenia stron internetowych z JavaScript, doszedłem do wniosku, że jest to niesamowicie potężny język i możesz robić z nim niesamowite rzeczy.

Oferuje bogaty zestaw funkcji, takich jak:

  • Pisanie dynamiczne
  • Funkcje pierwszej klasy
  • Funkcje zagnieżdżone
  • Domknięcia
  • Funkcje jako metody
  • Funkcje konstruktorów obiektów
  • Na bazie prototypów
  • Oparte na obiektach (prawie wszystko jest przedmiotem)
  • Regex
  • Literały tablicowe i obiektowe

Wydaje mi się, że prawie wszystko można osiągnąć za pomocą tego rodzaju języka, można również emulować programowanie OO, ponieważ zapewnia ono dużą swobodę i wiele różnych stylów kodowania.

Dzięki bardziej zorientowanym programowo niestandardowym funkcjom (I / O, FileSystem, urządzenia wejściowe itp.) Myślę, że wspaniale byłoby tworzyć aplikacje.

Chociaż, o ile mi wiadomo, jest on używany tylko w tworzeniu stron internetowych lub w istniejącym oprogramowaniu tylko jako język skryptowy.

Dopiero niedawno, być może dzięki silnikowi V8, był on częściej wykorzystywany do innych zadań (patrz na przykład node.js).

Dlaczego do tej pory sprowadza się tylko do tworzenia stron internetowych? Co powstrzymuje go od rozwoju oprogramowania?

Jose Faeti
źródło
8
Jeśli tworzenie stron internetowych nie jest (szczególnym przypadkiem) opracowywaniem oprogramowania, to czym właściwie jest? ...
Péter Török
@ Péter Török: Myślę, że rozumiesz. Chodzi mi o to, że do tej pory oprogramowanie było używane tylko jako język skryptowy w celu ulepszenia funkcji. Nigdy nie był używany do programowania aplikacji dla systemu operacyjnego.
Jose Faeti
4
Widzę dynamiczne pisanie jako ogromną wadę, a także chciałbym pozbyć się wartości zerowych.
Jonas
2
Masz na myśli „klasyczny rozwój aplikacji”, a nie „rozwój oprogramowania”, prawda? Lepiej odpowiednio zmień kurs.
Doc Brown
2
@JoseFaeti dla Windows 8 rekordów pozwala na pewne prace rozwojowe w HTML5 i JS
Raynos

Odpowiedzi:

14

Ostatnio node.js przyspieszył rozwój po stronie serwera. Tak więc teraz można napisać JavaScript do programowania.

To prawda. W historii nie był używany jako język programowania. Ale, hej, nawet tworzenie skryptów w środowisku klienta (User Agents) jest rodzajem rozwoju. Czyż nie

Głównym powodem, który słyszałem i czytałem na wielu blogach, jest to, że ludzie nie wiedzieli o jego mocy i wyjątkowości aż do ostatnich lat . Sprawiło to, że inne języki wykonały swoją pracę wystarczająco dobrze i nikt nigdy nie myślał o zrobieniu czegoś równoległego.

Saeed Neamati
źródło
Musi tak być i wygląda na to, że coś się teraz porusza :)
Jose Faeti
15

Od tutaj :

Zauważ, że wszystkie moje argumenty opieram na rzeczywistych przypadkach użycia. Kontrargumenty, których nie można kopii zapasowej przykładem użycia w prawdziwych, kompletnych, interesujących i użytecznych aplikacjach, są nieprawidłowe. Widziałem małe „demonstracje językowe”, które mają wszyscy inni, widziałem posty na blogu opisujące, w jaki sposób prototypy i dynamiczne pisanie tworzą trywialny mały przykład o kilka wierszy krótszy niż w języku C #, ale te po prostu nie są istotne na problemy, na które napotykasz pisanie prawdziwego kodu zamiast mikro-demonstracji i zabawek. Oto moje problemy z JS:

a) Magiczne „to”. To jest to, z wyjątkiem kiedy to jest to. JavaScript popycha cię do korzystania z anonimowych funkcji w dowolnym miejscu, z wyjątkiem tego, że zawsze tracą odpowiedni kontekst dla zmiennej „this”, więc w końcu masz głupi kod, taki jak „var _this = this”, i używasz tego w twoich callbackach lub innych funkcjach. W niektóre dni przysięgam, że liczba funkcji, które udaje mi się napisać i które nie używają przemianowanych „to”, są w rzeczywistości mniejsze niż liczba, która to robi.

b) 1 + „1” - 1 = 10. Również „1” + 0 = „10”. Tak, to faktycznie spowodowało błędy w naszych aplikacjach, w których dane, które powinny być liczbą, zostały załadowane z pliku JSON jako ciąg znaków z powodu błędu w innej aplikacji, a wynik nie był dobry. Cały nasz kod ładujący musiał zostać zaktualizowany, aby dodać mnóstwo konwersji typu w całym miejscu. Kiedy potrzebuję czegoś, aby być liczbą, naprawdę cholernie chcę, żeby to była liczba, a nie ciąg znaków, obiekt, zero lub cokolwiek innego. Lua, która pod wieloma względami jest bardzo podobna do JavaScript, naprawiła ten problem, po prostu nie będąc wystarczająco opóźnionym, aby użyć tego samego operatora do dodawania i łączenia łańcuchów.

c) Zmienne globalne domyślnie. Nawet jeśli weźmiesz argument, że dynamiczne pisanie jest po prostu „łatwiejsze”, ponieważ nie musisz myśleć o deklaracjach zmiennych, JavaScript wyrzuca ten argument przez okno, umieszczając „var” przed nowymi identyfikatorami w dowolnym miejscu . A potem cicho cię wkręca, jeśli zapomnisz.

d) Prototypy zamiast klas. Istnieje bardzo niewiele rzeczywistych aplikacji JavaScript na dużą skalę, które nie podłączają własnego systemu klas, aby obejść wrodzoną bezużyteczność prototypów w architekturze dużych aplikacji. Te same aplikacje w minimalnym stopniu wykorzystują prototypy w celu rozszerzenia podstawowych typów JavaScript i tylko dlatego, że JS był tak źle zaprojektowany, że nawet dwa ciekawe wbudowane typy, których on oferuje, nie mają połowy cech, których można by się spodziewać.

e) Niemożność tworzenia typów wartości dodanej. W rzeczywistości jest to częsty problem w prawie każdym języku oprócz C ++ / D. Dla tych, którzy używają JavaScript do pisania aplikacji WebGL, spójrz na wszystkie biblioteki algebry liniowej dla JavaScript. W aplikacjach 3D prawie używasz wektorów częściej niż skalarów. Wyobraź sobie, że każda liczba całkowita w Twojej aplikacji została przekazana przez odniesienie, tak że „a = 1; b = a; b ++” równa się aib równe 2. Każdy mały wektor trójskładnikowy jest kompletnym pełnym obiektem. Są one przekazywane przez odniesienie (źródło prawie połowy błędów w naszej dotychczasowej grze WebGL). Istnieją w ogromnej ilości, są przydzielane do sterty i są zbierane w śmieciach, co wywiera ogromną presję na GC, co może powodować i powoduje przerwy GC nawet w prostych grach WebGL, chyba że deweloper przeskoczy przez absurdalnie skomplikowane obręcze, aby uniknąć tworzenia nowych wektorów we wszystkich miejscach, w których logiczne jest tworzenie nowych wektorów. Nie możesz mieć przeciążenia operatora, więc masz bardzo duże i brzydkie wyrażenia do wykonywania podstawowych operacji. Dostęp do poszczególnych komponentów jest wolny. Obiekty nie są natywnie pakowane, a zatem są niezwykle wolno wpychane do bufora wierzchołków, chyba że zaimplementujesz je jako instancje Float32Array, co dezorientuje bzdury w optymalizatorach zarówno V8, jak i SpiderMonkey. Czy wspomniałem, że są przekazywane przez odniesienie? Dostęp do poszczególnych komponentów jest wolny. Obiekty nie są natywnie pakowane, a zatem są niezwykle wolno wpychane do bufora wierzchołków, chyba że zaimplementujesz je jako instancje Float32Array, co dezorientuje bzdury w optymalizatorach zarówno V8, jak i SpiderMonkey. Czy wspomniałem, że są przekazywane przez odniesienie? Dostęp do poszczególnych komponentów jest wolny. Obiekty nie są natywnie pakowane, a zatem są niezwykle wolno wpychane do bufora wierzchołków, chyba że zaimplementujesz je jako instancje Float32Array, co dezorientuje bzdury w optymalizatorach zarówno V8, jak i SpiderMonkey. Czy wspomniałem, że są przekazywane przez odniesienie?

f) Żadne wbudowane funkcje nie wymagają ani nie wymagają. Poważnie, wciąż. Biblioteki innych firm istnieją, ale prawie wszystkie mają jakiś błąd lub inny, z których co najmniej jest mylącym problemem buforowania w co najmniej Chrome, co sprawia, że ​​faktyczny rozwój jest uciążliwy.

g) Pisanie dynamiczne. Tak, jestem gotów rozpocząć ten argument. Zaczynasz zauważać to najbardziej, gdy przestajesz pisać małe aplikacje lub strony internetowe i zaczynasz pisać duże aplikacje, w których faktycznie masz dane, które trwają dłużej niż jedno kliknięcie myszą lub cykl żądania / odpowiedzi: dodaj niewłaściwy rodzaj obiektu do tablica do przetworzenia później i awaria później z powodu brakującej metody lub elementu w zupełnie innym bicie kodu niż w miejscu, w którym rzeczywiście wystąpił błąd. Dobre czasy. Tak, Java sprawia, że ​​wpisywanie statyczne wydaje się złe. Nie, Java / C # / C ++ nie są jedynym sposobem pisania statycznego. Wnioskowanie typu, niejawne powiązanie interfejsu itp. Zapewniają wszystkie zalety łatwego radzenia sobie i niewielkiej liczby naciśnięć klawiszy dynamicznego pisania bez wszystkich błędów. Drugi najpopularniejszy język WWW - ActionScript 3 - jest wpisywany statycznie, mimo że w przeciwnym razie jest identyczny z JS / ECMAScript. Nawiasem mówiąc, dostaję więcej awarii z aplikacji Python na moim pulpicie Fedory niż z aplikacji C / C ++ (właściwie żadna z aplikacji C / C ++ na awarii pulpitu, teraz o tym myślę). Brakujące wyjątki dla członków == o wiele łatwiejsze tworzenie i obsługa aplikacji, prawda?

h) Prędkość. Tak, ogromnie dużo wysiłku włożono w pracę wielu programistów, którzy sprawili, że JS był prawie o połowę szybszy niż kompilator C klasy niskiej, który jeden Junior Junior mógłby napisać w kilku miesięcy. LuaJIT jest w tej samej łodzi co JS pod względem podstawowych ograniczeń językowych, ale i tak radzi sobie lepiej niż każda implementacja JavaScript. Ludzie, którzy nie rozumieją, co faktycznie robią wszystkie optymalizacje JS w V8lubię twierdzić, że JS potrafi robić niesamowite rzeczy pod względem szybkości, ale w rzeczywistości wszystkie te optymalizacje są po prostu „bardzo bardzo starają się analizować kod w celu ustalenia typów zmiennych, a następnie skompilować go jak nieco opóźniony typ statyczny kompilator języka by to zrobił. ” Aha, jest śledzenie, ale wtedy śledzenie działa również na statycznie typowane języki (i działa lepiej ze względu na brak potrzeby ochrony typów w generowanym kodzie maszynowym). W rzeczywistości ani jedna z tych optymalizacji Whizbang nie została wymyślona przez JS lub dla niej; większość pochodzi z badań JVM (Java jest zła!) lub klasycznych języków OOP (prototypy są niesamowite!).

i) Nawet IntelliSense nie jest możliwy. Chcesz zobaczyć, jakie metody istnieją w zmiennej, którą masz w linii 187 foo.js w edytorze tekstu? Szkoda Prześledź kod, aż dowiesz się, gdzie został zainicjowany, a następnie prześledź kod, aby dowiedzieć się, co ma na nim jego prototyp. A potem mam nadzieję, że nie ma kodu dynamicznie zmieniającego prototyp za twoimi plecami. W rzeczywistości, po prostu uruchom go w przeglądarce i ustaw punkty przerwania, ponieważ znalezienie jakiejkolwiek użytecznej wartości w jakikolwiek inny sposób jest w zasadzie niemożliwe dla dowolnej bazy kodu większej niż witryny toy_web_app.html, których apologeci JavaScript używają do gloryfikowania łatwości i prostoty JavaScript. Niektóre edytory kodu starają się naprawdę lepiej, i prawie w pewnym sensie odnoszą sukces w naprawdę prostych przypadkach, czasami raz.

j) Brak korzyści. JavaScript nie jest nawet specjalny w porównaniu do innych dynamicznie pisanych języków. Nie jest w stanie zrobić nic interesującego, czego nie mogą zrobić także Lua, Python, Ruby itp. Żadna z implementacji JS nie jest szybsza niż LuaJIT lub PyPy ani inne zaawansowane implementacje JIT innych dynamicznych Języki. JS nie ma plusów w porównaniu z innymi powszechnie dostępnymi językami. Och, z wyjątkiem tego, że działa natywnie w przeglądarce internetowej bez wtyczki. To jedyny powód na świecie, dlaczego jest tak popularny. W rzeczywistości jest to jedyny powód, dla którego zdarzenie istnieje. Jeśli ktoś 10 lat temu pomyślał: „do diabła, upuśćmy do naszej przeglądarki istniejący dobrze zaprojektowany i dobrze ugruntowany język i niech inni zrobią to samo, zamiast zmuszać wszystkich do korzystania z tego głupiego, małego hackjoba, który wymyślił NetScape , „Internet wyglądałby dzisiaj znacznie (lepiej). Wyobraź sobie przyszłość, jeśli Chrome upuści Pythona w Chrome jako obsługiwanym języku. A właściwie wyobraź sobie: Google upuszcza C / C ++ w Chrome jako obsługiwany język (http://code.google.com/p/nativeclient/).

17 z 26
źródło
To naprawdę interesujący post. Byłbym ciekawy jego przypadków użycia, które stanowią podstawę jego argumentów. Nie zgadzam się z jego argumentami, ale rozwijam aplikacje JS wielkości korporacyjnej od prawie 10 lat i nie spotkałem się z niektórymi rzeczami, o których wspominał (w szczególności jego pierwszą uwagą na temat „magii to”). Opierając się na własnym doświadczeniu, argumenty przeciwko javascript, takie jak te w tym poście, są zwykle wysuwane przez ludzi o ciężkim tradycyjnym pochodzeniu od środowiska ... w takim przypadku zrozumiałbym jego zamieszanie.
Pan JavaScript
Interesujące jest to, że w 2016 roku odpowiedź jest obecnie całkowicie nieaktualna z powodu ewolucji języka.
Stephan Bijzitter
@Pan. JavaScript Cześć. Czy znasz serię samouczków, które koncentrują się na rozwiązywaniu przykładów rzeczywistych problemów, a nie tylko na badaniu JavaScript oraz jego funkcji i mechanizmów? Nie mam szczęścia w wyszukiwaniu słów kluczowych. Na przykład zamiast przejść przez tak szczegółowy link do samouczka oraz jego miliony przykładów i funkcji, gdzie znajduję repozytorium małych samouczków na temat tworzenia aplikacji GUI do zarządzania systemem ubezpieczeń, lekarzami, szkołą lub częścią operacyjną supermarket? Dziękuję
Hannes,
12

Dlaczego?

JavaScript najbardziej niezrozumiany język

Byliśmy w średniowieczu i nadal jesteśmy w stanie zaakceptować fakt, że JavaScript jest potężnym i wszechstronnym językiem. To po prostu nie jest główny nurt.

Jedynym niedawnym postępem jest to, że node.js stał się męczący i ludzie zaczynają akceptować, że javascript ma inne zastosowania.

Miałem oko na rozwój JS i HTML5 dla Windows 8, a reakcja społeczności .NET brzmiała: „Dobry Boże, dlaczego?”.

Jest to po prostu fakt, że większość stron internetowych wciąż widzi JavaScript jako język zabawek, którego używasz do przewijania menu w przeglądarkach.

Trzeba przyznać, że JavaScript nie jest zgodny z „nowoczesnymi praktykami programistycznymi”. Dla mnie JavaScript jest wciąż językiem hakerskim, którego używam z vimem, a internet to moja dokumentacja. Nie ma IDE, nie ma narzędzi programistycznych, nie ma autouzupełniania ani „inteligencji”, nie ma graficznych interfejsów klikania i przeciągania.

W świecie programistów Java i .NET są oni przywiązani do GUI i IDE i nie byliby w stanie programować w vimie.

Raynos
źródło
1
Zgadzam się z tobą, z wyjątkiem: „Nie ma IDE, nie ma narzędzi programistycznych, nie ma autouzupełniania ani„ inteligencji ”, nie ma graficznych interfejsów klikania i przeciągania”. Właściwie to wszystko można uzyskać za pomocą wielu różnych IDE, używam na przykład Visual Studio i jest po prostu świetne.
Jose Faeti
1
@JoseFaeti przepraszam, Visual Studio nie jest IDE javascript. Jestem szybszy w vimie niż w VS2010. Oznacza to, że VS2010 to nieszczelny JS IDE.
Raynos
2
@Raynos, „Jestem szybszy w vimie niż w VS2010. Oznacza to, że VS2010 to nieszczelny JS IDE”. - a może to po prostu oznacza, że ​​nie znasz VS tak dobrze jak vim.
Péter Török,
2
Absolutnie nie, ale nie zamierzam budować frontonu RIA w Silverlight, ponieważ uwielbiam Resharper i LINQ lub aplikację ASP.Net MVC z cienką warstwą jQuery, ponieważ znów jest przyjazna .Net, gdy dostępne są bogate języki JavaScript po stronie klienta które lepiej nadają się do pracy.
sa93
1
Dodałem tylko mój głos do refrenu ludzi twierdzących, że istnieją IDE JavaScript. Szczerze mówiąc, głupie jest twierdzenie, że jest inaczej. IDE mogą Ci się nie podobać i mogą nie być idealne, ale nadal są IDE. Czy też wyobrażałem sobie inteligencję i uzupełnianie kodu VS podczas pracy z JS?
Ian Newson
10

Twoja lista nie zawiera niczego na temat zapisywania plików w systemie, co stanowi ogromną część rozwoju oprogramowania.

Ludzie nie pomyśleliby o użyciu JS do budowy aplikacji, ponieważ jest to de facto język skryptowy dla sieci, a ty zawsze używałbyś odpowiedniego narzędzia do tego zadania.

Po co pisać akry JS, aby wypisać plik, gdy jest to trywialna operacja w Javie / .NET / C / C ++?

Biorąc to pod uwagę, jak wspomnieli inni, node.js i jego biblioteki sprawiły, że operacje po stronie serwera stały się trywialne, a wraz z popularyzacją node.js nauka tego stanie się umiejętnością CV, ponieważ będziesz w stanie utrzymać / rozszerzyć / zbudować aplikacje z tym.

StuperUser
źródło
1
+1 całkowicie zapomniało, jak ważna jest biblioteka stdio.
Raynos,
1
W systemie plików, jak go ująłeś, mamy teraz lokalne interfejsy API do przechowywania danych, chociaż nie liczyłbyś na nie za dużą trwałość. Jednak pisanie do systemu plików nie musi być bezpośrednie, javascript może wykonywać spokojne wywołania do serwera, który (napisany w LOLCode lub w C lub JS) zapisuje w jakiejś formie pamięci.
sa93
1
Po stronie serwera. Interfejs API pliku NodeJS jest po prostu trywialny jak C etc ... <- jeśli robisz poprawnie IO w C (nie blokuje). Również połączenie Ajax z dowolnym rozsądnym opakowaniem może mieć 2-3 linie. MyLib.Ajax.post ('/ persistence / Something', {data: blahObj})
sa93
@ sa93, proszę nie mylić środowisk hosta przeglądarki z JavaScript. localStorage to interfejs API hosta w przeglądarkach. Nie jest to zdefiniowane w specyfikacji ES5.
Raynos
1
@reinierpost Writing files to the file system has been replaced with HTTP POST.Nie, jeśli piszesz interfejsy API obsługujące posty.
StuperUser
5

Większość powszechnie używanych języków jest mocniejsza i lepiej zaprojektowana niż JavaScript. Wszystkie wymienione funkcje są obsługiwane przez inne dynamiczne języki, takie jak Python lub Ruby, które są ogólnie lepiej zaprojektowane. Niektóre z wymienionych przez Ciebie funkcji i tak niekoniecznie są pożądane - wiele osób uważa, że ​​pisanie statyczne z wnioskowaniem typu jest lepsze niż pisanie dynamiczne, jeśli masz wybór.

Nie mówię tego o diss JavaScript. Bardzo lubię pracować z JS przy tworzeniu stron internetowych. Ale patrząc na to obiektywnie, JS ma wiele wad w porównaniu do innych języków:

  • Liczne nieusuwalne wady. Popełniano wiele błędów podczas początkowego opracowywania JS. Nie trzeba ich tutaj wymieniać, są dobrze udokumentowane. We wszystkich językach występują błędy w początkowym projekcie, które są później naprawiane. Różnica w stosunku do JS polega na tym, że język został opracowany i wydany zbyt szybko, a tych błędów nigdy nie można naprawić ze względu na wymaganą zgodność wsteczną w przeglądarkach.
  • Niezwykle wolny proces wprowadzania ulepszeń i nowych funkcji. Ponieważ wszyscy producenci przeglądarek muszą się zgodzić i mogą nawet z różnych powodów politycznych chcieć spowolnić rozwój języka. Spójrz na C #, który jest w rzeczywistości nowszym językiem niż JS. Po wprowadzeniu C # nie miał np. zamknięcia lub funkcje wyższego rzędu, takie jak JS, ale po wielu iteracjach ma teraz to wszystko, a ponadto funkcje takie jak Linq i składnia asynchroniczna, której programiści JavaScript mogą tylko zazdrościć.
  • Zubożała biblioteka standardowa. Nowoczesne języki, takie jak Python, Ruby lub cokolwiek opartego na Javie lub .net, mają rozbudowane standardowe biblioteki dla prawie wszystkiego, czego potrzebujesz. W JS nie można nawet odczytać pliku bez bibliotek stron trzecich. Wspominasz o Regex, ale wszystkie nowoczesne języki mają to i tysiąc innych rzeczy.
  • Inne języki dogoniły kilka zalet JavaScript. Funkcje takie jak zamknięcia i pierwszorzędne funkcje były potężne w porównaniu do niezgrabnych języków statycznych, takich jak Java dziesięć lat temu, ale języki dynamiczne i funkcjonalne już od dawna mają takie funkcje, a nawet Java, dość konserwatywny język, dodał to w Javie 8.

Jedyną cechą, która tak naprawdę odróżnia JavaScript od innych współczesnych języków, jest dziedziczenie prototypowe (w przeciwieństwie do klasowego), a zaletą tego modelu jest wątpliwe, ponieważ wszyscy po prostu używają go do emulacji dziedziczenia klasowego.

Po prostu nie ma powodu, aby wybierać JavaScript, jeśli masz możliwość wyboru innego nowoczesnego języka. Jedynym powodem byłoby, gdyby był to jedyny język, który znasz.

JacquesB
źródło