Czy JavaScript jest językiem bez typu?

104

Zauważyłem, że niektórzy nazywają JavaScript językiem „dynamicznie, słabo typizowanym”, ale niektórzy mówią nawet „bez typu”? Co to naprawdę jest?

Deniz Dogan
źródło

Odpowiedzi:

133

JavaScript nie ma typu:


(źródło: no.gd )

Nawet Brendan Eich tak mówi. Na Twitterze odpowiedział w wątku zawierającym link do tego pytania:

... typy akademickie używają „bez typu” na oznaczenie „brak typów statycznych” ...

Problem polega na tym, że istnieje kilka różnych definicji braku typu .

Jedna z definicji została omówiona w jednej z powyższych odpowiedzi - środowisko wykonawcze nie oznacza wartości i po prostu traktuje każdą wartość jako bity. JavaScript ma wartości zmiennych i ma różne zachowanie na podstawie tych tagów. Więc JavaScript oczywiście nie pasuje do tej kategorii.

Druga definicja pochodzi z teorii języka programowania (akademicka rzecz, do której odnosi się Brendan). W tej domenie brak typu oznacza po prostu, że wszystko należy do jednego typu .

Czemu? Ponieważ język wygeneruje program tylko wtedy, gdy może udowodnić, że typy są wyrównane (aka korespondencja Curry-Howarda ; typy to twierdzenia, programy to dowody). Oznacza to w języku bez typu:

  1. Program jest zawsze generowany
  2. Dlatego typy zawsze pasują do siebie
  3. Dlatego musi istnieć tylko jeden typ

W przeciwieństwie do języka maszynowego:

  1. Program mógł nie zostać wygenerowany
  2. Ponieważ typy mogą się nie zgadzać
  3. Ponieważ program może zawierać wiele typów

Więc proszę bardzo, w PLT, brak typu oznacza po prostu wpisywanie dynamiczne, a wpisywanie oznacza po prostu wpisywanie statyczne . W tej kategorii zdecydowanie nie ma kodu JavaScript.

Zobacz też:

Brian McKenna
źródło
6
Oczywiście „brak typów statycznych” to nie to samo, co „brak deklaracji typów”.
Andreas Rossberg
+1. Być może powinieneś również połączyć to w swojej odpowiedzi. Te „słabo wpisane” bs są zbyt rozpowszechnione.
missingfaktor
2
Teoria języka programowania jest poprawna. Gigantyczny zrzut ekranu jest nieprawidłowy.
Alex W
2
Ucieszyłem się, widząc, że ta odpowiedź odnosi się do posta na blogu Harpera, ale byłoby miło, gdyby społeczność PLT porzuciła „bez typu” na rzecz „bez kategorii”. Definicja „bez typu”, oznaczająca „tylko bity”, ma sens. Używanie „untyped” do opisu języka, którego formalna specyfikacja używa słowa „type” i mówi, że ma siedem typów (Undefined, Null, Number, String, Boolean, Symbol i Object) jest naprawdę mylące. Większość ludzi nie chce odróżniać tego rodzaju pojęcia od def. PLT.
Ray Toal
4
Twój 1. 2. 3.dla nietypowego języka nie pasuje do JavaScript. Jest nie tylko jeden typ - jest ich około 4-5. Jak więc to pokazuje, że JavaScript jest nietypowy?
Don Cheadle
82

mocne / słabe można rozpatrywać w odniesieniu do sposobu, w jaki kompilator, jeśli ma to zastosowanie, obsługuje pisanie.

  • Słabo wpisany oznacza, że ​​kompilator, jeśli ma to zastosowanie, nie wymusza poprawnego wpisywania. Bez niejawnego wykrzyknika kompilatora instrukcja będzie powodować błąd w czasie wykonywania.

    "12345" * 1 === 12345  // string * number => number

    Silnie wpisany oznacza, że ​​istnieje kompilator i chce, abyś jawnie rzutował z łańcucha na liczbę całkowitą .

    (int) "12345" * 1 === 12345

    W obu przypadkach niektóre funkcje kompilatora mogą niejawnie zmienić instrukcję podczas kompilacji, aby wykonać konwersję za Ciebie, jeśli może określić, że jest to właściwe.

    Jak dotąd JavaScript można sklasyfikować jako nieposiadający silnej typizacji. Oznacza to, że jest napisany słabo lub nie.

dynamiczny / statyczny można rozpatrywać w odniesieniu do sposobu, w jaki instrukcje językowe manipulują typami.

  • Typ dynamiczny oznacza, żewymuszany jest typ wartości , ale zmienna po prostu reprezentuje dowolną wartość dowolnego typu.

    x = 12345;    // number
    x = "string"; // string
    x = { key: "value" }; // object
    y = 123 + x; // error or implicit conversion must take place.

    Typ statyczny oznacza, żetyp zmiennej jest silnie wymuszany, a typ wartości jest wymuszany mniej.

    int x = 12345; // binds x to the type int
    x = "string";  // too late, x is an integer - error
    string y = 123; // error or implicit conversion must take place.

    Jak dotąd JavaScript można sklasyfikować jako niestatycznie typowany. Wydaje się również, że jest wpisywany dynamicznie, jeśli w ogóle zostanie wpisany. Musimy więc zobaczyć, co oznacza pisanie.

Typed oznacza, że ​​język rozróżnia różne typy, takie jak string , number , boolean , object , array , null , undefined i tak dalej. Każda operacja jest również związana z określonymi typami. Nie możesz więc podzielić liczby całkowitej przez łańcuch .

    2 / "blah"  // produces NaN

Bez typu oznacza, że ​​operacja dzielenia liczby całkowitej przez łańcuch oznaczałaby traktowanie pierwszych czterech bajtów łańcucha jako liczby całkowitej . Dzieje się tak, ponieważ operacje bez typów odbywają się bezpośrednio na bitach, nie ma typów do obserwowania. Wynik będzie całkiem nieoczekiwany:

    2 / "blah"  // will be treated as  2 / 1500275048

Ponieważ JavaScript zachowuje się zgodnie z definicją bycia typowanym, tak musi być. Dlatego musi być typowany dynamicznie i słabo.

Jeśli ktoś twierdzi, że JavaScript nie ma typu, to jest to tylko dla teorii akademickiej, a nie dla praktycznego zastosowania.

Gumbo
źródło
1
Ale myślę, że w ostatnim stwierdzeniu jest sprzeczność. W JavaScript wynik dzielenia liczb całkowitych na łańcuchy jest dobrze zdefiniowany dla dowolnej wartości liczby całkowitej lub łańcucha. Po prostu nie jest to zbyt przydatne!
Deniz Dogan
Jeśli masz lepszą definicję / opis, możesz ją edytować. Dlatego stworzyłem wiki społeczności.
Gumbo
@skurpur: Całkowicie zamieniłeś znaczenie pisania dynamicznego i słabego - poprawiłeś to.
Rene Saarsoo
Och, przepraszam, edytowałeś go, ja też go edytowałem i nadpisałem twoje zmiany.
Rene Saarsoo
3
-1. Musisz przeczytać ten .
missingfaktor
48

JavaScript jest napisany słabo . Z pewnością nie jest „bez typu”, ale jego słabo typizowany charakter zapewnia dużą elastyczność w zakresie niejawnych konwersji.

Pamiętaj, że JavaScript jest również wpisywany dynamicznie. Ta metoda pisania pozwala na coś, co nazywa się „pisaniem kaczym” .

Dla porównania należy wziąć pod uwagę, że JavaScript nie jest typowany silnie ani statycznie. Czasami zrozumienie, czym coś nie jest, może pomóc ci lepiej zobaczyć, co to jest.

Andrew Hare
źródło
2
-1. Musisz przeczytać ten .
missingfaktor
3
Ta odpowiedź jest znacznie lepsza i znacznie dokładniejsza niż odpowiedź najczęściej głosowana.
Alex W
3
@JimboJonny: Nieprawidłowe. Chyba że w obecności programisty Assembly, stwierdzenie, że każdy język jest wpisany na maszynie, nie byłoby zbyt niepoprawne. Bez typu oznacza, że ​​jedyne operacje dotyczą bezpośrednio manipulacji bitami. Ale weź pod uwagę, że JavaScript ma metody toString () i parseInt (). Nie wpisuj więcej niż to.
Suamere,
2
@Suamere - Oto cytat z „Javascript: The Definitive Guide” autorstwa O'Reilly: „Istotną różnicą między JavaScript a językami takimi jak Java i C jest brak typu JavaScript. Oznacza to po części, że zmienna JavaScript może przechowywać wartość dowolnego typu danych, w przeciwieństwie do zmiennej Java lub C, która może przechowywać tylko jeden określony typ danych, dla którego została zadeklarowana. ”
Jimbo Jonny,
3
Więc jeśli kupisz BS, to jakiś koleś twierdzi, że akademicy celowo używają słowa „bez typu” w znaczeniu „dynamicznie wpisywane”. Więc tak, JavaScript nie jest definiowany przez wszystkie twoje dowody. Ale jeśli wiesz, że „bez typu” jest niepoprawnie używane do reprezentowania języków, które są naprawdę „wpisywane dynamicznie”, po prostu nazwij języki dang „dynamicznie typowane”. tinyurl.com/czhcv54
Suamere,
8

Według autora JavaScript jest również klasyfikowany jako dynamicznie typowany . Witryna Wiki stwierdza, że ​​języki dynamicznie typowane są sprawdzane w czasie wykonywania, a nie w kompilatorze, podczas gdy słabo typowane odnosi się do możliwości zmiany typu w locie w kodzie. Więc tak, jest to zarówno wpisane dynamicznie, jak i słabo.

Darren Newton
źródło
6

Problem w tym, że wielu programistów jest dezorientujący, polega na tym, że takie definicje nie są gdzieś ustandaryzowane. Termin nietypowy język programowania jest niejednoznaczny. Czy to odnosi się do języka, który nie ma typów danych lub języka, który jest wariantem bez typu rachunku lambda ?

JavaScript / ECMAScript ma system typów i wszystkie domeny jego funkcji akceptują dowolny typ specyfikacji referencyjnej. Oznacza to, że w rzeczywistości JavaScript ma jeden typ danych. To kwestia implementacji, która jest ważniejsza dla bardzo zaawansowanych programistów JavaScript. Przeciętny programista JavaScript dba tylko o abstrakcyjne typy danych języka , które zostały określone przez ECMAScript.

W kontekście zwykłego programisty, a nie naukowca czy informatyka teoretycznego, termin „ nietypowy” jest mylący, ponieważ większość ludzi nie robi rachunku lambda. W ten sposób termin dezorientuje masy i wydaje się deklarować, że JavaScript nie ma żadnych typów danych, co jest po prostu nieprawdą. Każdy, kto kiedykolwiek używał, typeofwie, że JavaScript ma własne typy danych języka:

var test = "this is text";
typeof(test);

plony

"strunowy"

ECMAScript definiuje następujące typy dla języka: undefined, null, string, boolean, number,object

http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

Bardziej dokładne oznaczenie dla JavaScript byłoby niejawnie wpisane, wpisane dynamicznie lub słabo / luźno wpisane (lub ich kombinacje), ponieważ JavaScript używa w niektórych przypadkach wymuszania typu, co powoduje, że typ jest niejawny, ponieważ nie trzeba jawnie określać typ swoich zmiennych. Podlega słabo typizowanym, ponieważ w przeciwieństwie do niektórych języków, w których rozróżnia się liczby zmiennoprzecinkowe i całkowite itp., Używa tylko jednego numbertypu, aby objąć wszystkie liczby i wykorzystuje wymuszenie typu wspomnianego wcześniej [sekcja 9 specyfikacji ECMAScript] , w przeciwieństwie do język silnie typizowany, który miałby bardzo specyficzne typy danych (tj. musiałbyś określić intlub float).

Definicje języków z typowaniem statycznym i dynamicznym nie są ustandaryzowane, jednak nie ma też rozmiaru bajtu, gdy komputery zaczynały ewoluować. Pisanie statyczne i dynamiczne najczęściej odnosi się do obecności pewnych cech języka. Jednym z nich jest sprawdzanie typów w czasie wykonywania lub tak zwane dynamiczne sprawdzanie typów . Jeśli używałeś JavaScript, już wiesz, że zdecydowanie czeka on do czasu wykonania, aby sprawdzić typy, dlatego TypeErrorpodczas wykonywania kodu pojawiają się wyjątki. Przykład tutaj

Myślę, że najczęściej wybieraną odpowiedzią jest mylenie polimorfizmu funkcji JavaScript z funkcjami, które akceptują dosłownie wszystko (jak w przypadku nietypowych wariantów rachunku Lambda), co jest błędem asocjacyjnym .

Alex W.
źródło
To nie jest błędna nazwa, ale kontekst ma znaczenie, patrz stackoverflow.com/questions/9154388/ ...
Andreas Rossberg
@AndreasRossberg To absolutnie jest mylące. To, do czego odnosisz się w swoim bezwstydnie promowanym przez siebie linku , to system typów. Powodem, dla którego termin jest błędny, jest to, że jest niejednoznaczny. Większość programistów, gdy słyszą o języku bez typu, myśli, że typ danych nie jest systemem typów . Myślę, że komentarz Konrada Rudopha naprawdę podkreśla ten punkt widzenia.
Alex W
Nie wiem, dlaczego odnoszenie się do mojej poprzedniej odpowiedzi zamiast powtarzania jej tutaj jest „bezwstydne”. Ponadto jasno powiedziałem, że kontekst ma znaczenie. W przeciwieństwie do zarzutu K. Rudolpha, w literaturze istnieją doskonale spójne i powszechnie akceptowane definicje „systemu typów”, zacytowałem jedną. Oczywiście możesz uznać je za mylące w swoim kontekście, ale to nie czyni ich „błędnymi”.
Andreas Rossberg
@AndreasRossberg Kontekst jest tutaj bardzo ważny. W odpowiedzi, która otrzymała najwięcej głosów, brzmi „untyped = brak deklaracji typu”, co jest wyraźnie niepoprawne. Mówię, że w tym kontekście jest to błędne określenie. Nikt nie wspomniał tutaj o rachunku lambda, a zrobienie tego jest nieco pretensjonalne w tym prostym przypadku.
Alex W
1

Pamiętaj, że JavaScript pozwala zapytać, co to jest typeof(your_variable), i porównać typy: 5==="5"zwraca false. Dlatego nie sądzę, że można to nazwać bez typu.

Jest dynamicznie i (oceniany jako) słabo typizowany. Możesz chcieć wiedzieć, że używa on pisania kaczego (patrz link Andrew) i oferuje OOP poprzez Prototypowanie zamiast klas i dziedziczenia.

instancja mnie
źródło
Wpisywanie zmiennej nie ma nic wspólnego z rzutowaniem wartości. Ma to związek z deklaracjami typów zmiennych. Javascript nie ma żadnej konstrukcji do tego w ogóle, dlatego tak niewielu javascripterów nawet rozumie tę koncepcję i dlaczego tak wielu z nich błędnie interpretuje pisanie zmiennych jako coś związanego z porównywaniem lub rzutowaniem typów zmiennych. W JS nie można W ogóle deklarować String a = "blah";ani var a:String = 'blah';(tj. Zmiennych wpisywanych). Dlatego nie ma typu.
Jimbo Jonny
0

Gdy jest wpisany (możesz zapytać „typeof someVar” i poznać jego konkretny typ, jest bardzo słaby.

Dany:

  var a = "5";

można powiedzieć, że a jest łańcuchem. Jeśli jednak napiszesz:

  var b = a + 10;

b jest liczbą int równą 15, więc a zachowuje się jak int. Oczywiście możesz wtedy napisać:

  var c = a + "Hello World";

a c będzie równe „5Hello World”, więc a znowu zachowuje się jak ciąg.

James Curran
źródło
1) Rzutowanie wartości! = Wpisanie zmiennej 2) nie jest słaba, nie istnieje. Nie możesz wpisać zmiennej w javascript.
Jimbo Jonny,
Ciekawe, dlaczego ta odpowiedź otrzymała dwa głosy negatywne. Definicja, którą znalazłem w przypadku słabego pisania, mówi dokładnie tak: Typ wartości jest określany na podstawie sposobu jej użycia.
aioobe
Czy to prawda? Dostaję brówne 510: ideone.com/BRcSW7
aioobe