Apakah JavaScript adalah bahasa yang tidak diketik?

104

Saya telah menemukan bahwa beberapa orang menyebut JavaScript sebagai bahasa yang "diketik dengan lemah secara dinamis", tetapi beberapa bahkan mengatakan "tidak diketik"? Benarkah itu?

Deniz Dogan
sumber

Jawaban:

133

JavaScript tidak diketik:


(sumber: no.gd )

Bahkan Brendan Eich mengatakan demikian. Di Twitter, dia membalas utas yang terkait dengan pertanyaan ini:

... tipe akademis menggunakan "tanpa tipe" yang berarti "tidak ada tipe statis" ...

Jadi masalahnya adalah ada beberapa definisi berbeda dari untyped .

Satu definisi telah dibicarakan di salah satu jawaban di atas - runtime tidak menandai nilai dan hanya memperlakukan setiap nilai sebagai bit. JavaScript melakukan nilai tag dan memiliki perilaku berbeda berdasarkan tag tersebut. Jadi JavaScript jelas tidak cocok dengan kategori ini.

Definisi lainnya adalah dari Teori Bahasa Pemrograman (hal akademis yang dimaksud Brendan). Dalam domain ini, tanpa tipe berarti semuanya termasuk dalam satu jenis .

Mengapa? Karena bahasa hanya akan menghasilkan program jika dapat membuktikan bahwa jenisnya selaras (alias korespondensi Curry-Howard ; jenis adalah teorema, program adalah bukti). Artinya dalam bahasa yang tidak diketik:

  1. Sebuah program selalu dibuat
  2. Oleh karena itu jenisnya selalu cocok
  3. Oleh karena itu, hanya boleh ada satu jenis

Berbeda dengan bahasa yang diketik:

  1. Program mungkin tidak dibuat
  2. Karena tipe mungkin tidak cocok
  3. Karena sebuah program bisa berisi banyak tipe

Jadi begitulah , di PLT, untyped berarti diketik secara dinamis dan diketik berarti diketik secara statis . JavaScript jelas tidak diketik dalam kategori ini.

Lihat juga:

Brian McKenna
sumber
6
Dan tentu saja, "tanpa tipe statis" juga tidak sama dengan "tanpa deklarasi tipe".
Andreas Rossberg
+1. Anda mungkin juga harus menghubungkan ini dalam jawaban Anda. Bs yang "diketik lemah" ini terlalu tersebar luas.
missingfaktor
2
Teori Bahasa Pemrograman benar. Tangkapan layar raksasa salah.
Alex W
2
Saya senang melihat jawaban ini mereferensikan postingan blog Harper, tetapi alangkah baiknya jika komunitas PLT menghapus "untyped" dan mendukung "unityped". Definisi "untyped" yang berarti "hanya bit" sebenarnya masuk akal. Menggunakan "untyped" untuk mendeskripsikan bahasa yang spesifikasi formalnya menggunakan kata "type" dan mengatakan bahwa ia memiliki tujuh jenis (Undefined, Null, Number, String, Boolean, Symbol, dan Object) benar-benar membingungkan. Kebanyakan orang tidak ingin membedakan pengertian jenis ini dari def PLT.
Ray Toal
4
Bahasa Anda 1. 2. 3.untuk bahasa yang tidak diketik tidak cocok dengan JavaScript. Tidak hanya ada satu jenis - ada sekitar 4 - 5. Jadi, bagaimana cara menunjukkan JavaScript tidak diketik?
Don Cheadle
82

kuat / lemah dapat dipikirkan dalam kaitannya dengan bagaimana kompilator, jika berlaku, menangani pengetikan.

  • Ketik yang lemah berarti kompilator, jika berlaku, tidak memaksakan pengetikan yang benar. Tanpa interjeksi compiler implisit, instruksi akan error selama run-time.

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

    Diketik dengan kuat berarti ada kompiler, dan ia ingin Anda melakukan cast eksplisit dari string ke integer .

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

    Dalam kedua kasus, beberapa fitur kompiler dapat secara implisit mengubah instruksi selama waktu kompilasi untuk melakukan konversi untuk Anda, jika dapat menentukan bahwa itu adalah hal yang benar untuk dilakukan.

    Sejauh ini, JavaScript dapat dikategorikan sebagai Not-Strongly-Typed. Itu berarti itu diketik lemah atau tidak diketik.

dinamis / statis dapat dianggap dalam kaitannya dengan bagaimana instruksi bahasa memanipulasi tipe.

  • Diketik secara dinamis berarti jenis nilai diterapkan, tetapi variabel hanya mewakili nilai apa pun dari jenis apa pun.

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

    Diketik secara statis berartijenis variabel diberlakukan dengan kuat, dan jenis nilai kurang diberlakukan.

    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.
    

    Sejauh ini, JavaScript dapat dikategorikan sebagai Not-Statically-Typed. Juga, tampaknya Dynamically Typed, jika diketik sama sekali. Jadi kita perlu melihat apa arti Mengetik.

Typed berarti bahasanya membedakan antara tipe yang berbeda seperti string , number , boolean , object , array , null , undefined ,dan sebagainya. Juga setiap operasi terikat pada tipe tertentu. Jadi Anda tidak bisa membagi integer dengan string .

    2 / "blah"  // produces NaN

Untyped berarti operasi membagi integer dengan string akan menghasilkan perlakuan empat byte pertama dari string sebagai integer . Ini karena operasi tanpa tipe berlangsung langsung pada bit, tidak ada tipe yang harus diamati. Hasilnya akan menjadi sesuatu yang sangat tidak terduga:

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

Karena JavaScript berperilaku sesuai dengan definisi Typed, maka JavaScript haruslah. Dan karena itu harus Dynamically Typed, dan Weakly Typed.

Jika ada yang mengklaim JavaScript adalah Untyped, itu hanya untuk teori akademis, bukan untuk aplikasi praktis.

Gumbo
sumber
1
Tapi saya pikir ada kontradiksi dalam pernyataan terakhir. Dalam JavaScript, hasil dari pembagian string-integer didefinisikan dengan baik, untuk nilai integer atau string apa pun. Itu tidak terlalu berguna!
Deniz Dogan
Jika Anda memiliki definisi / deskripsi yang lebih baik, silakan edit. Itu sebabnya saya menjadikannya wiki komunitas.
Gumbo
@skurpur: Anda telah sepenuhnya menukar arti dari pengetikan Dinamis dan Lemah - memperbaikinya.
Rene Saarsoo
Oh, maaf, Anda mengeditnya saat saya juga mengeditnya dan saya menimpa perubahan Anda.
Rene Saarsoo
3
-1. Anda perlu membaca ini .
missingfaktor
48

JavaScript diketik dengan lemah . Ini pasti bukan "tidak diketik" tetapi sifatnya yang lemah ketik memungkinkan banyak fleksibilitas dalam hal konversi implisit.

Perlu diingat bahwa JavaScript juga diketik secara dinamis. Metode pengetikan ini memungkinkan apa yang dikenal sebagai "mengetik bebek" .

Sebagai perbandingan, pertimbangkan bahwa JavaScript tidak diketik dengan kuat dan juga tidak diketik secara statis. Terkadang memahami apa yang tidak dapat membantu Anda melihat apa itu dengan lebih baik.

Andrew Hare
sumber
2
-1. Anda perlu membaca ini .
missingfaktor
3
Jawaban ini jauh lebih baik, dan jauh lebih akurat, daripada jawaban pilihan teratas.
Alex W
3
@JimboJonny: Tidak benar. Kecuali jika ada pengembang Assembly, Tidaklah terlalu salah untuk menyatakan bahwa setiap bahasa diketik. Tanpa tipe berarti satu-satunya operasi secara langsung pada manipulasi bit. Tetapi pertimbangkan bahwa Javascript memiliki metode toString () dan parseInt (). Jangan mengetik lebih dari itu.
Suamere
2
@Suamere - Berikut kutipan dari "Javascript: Panduan Definitif" dari O'Reilly: "Perbedaan penting antara JavaScript dan bahasa seperti Java dan C adalah JavaScript tidak diketik. Ini berarti, sebagian, variabel JavaScript dapat menyimpan nilai jenis data apa pun, tidak seperti variabel Java atau C, yang hanya dapat menampung satu jenis data tertentu yang dideklarasikan. ”
Jimbo Jonny
3
Jadi, jika Anda setuju dengan BS bahwa beberapa orang mengklaim bahwa para akademisi sengaja menggunakan kata "tidak diketik" untuk berarti "diketik secara dinamis." Maka ya, JavaScript tidak diketik oleh semua bukti Anda. Tetapi jika Anda tahu bahwa " tidak diketik" salah digunakan untuk mewakili bahasa yang benar-benar "diketik secara dinamis", maka panggil saja bahasa dang "diketik secara dinamis". tinyurl.com/czhcv54
Suamere
8

Bagi penulis, JavaScript juga diklasifikasikan sebagai Dynamically typed . Wiki menyatakan bahwa bahasa yang diketik secara dinamis adalah jenis yang diperiksa pada saat runtime alih-alih dalam kompiler sementara Diketik Lemah mengacu pada kemampuan untuk mengubah jenis dengan cepat dalam kode Anda. Jadi ya, keduanya diketik secara dinamis DAN diketik Lemah.

Darren Newton
sumber
6

Masalah di sini yang membingungkan banyak programmer adalah definisi seperti ini tidak distandarisasi di suatu tempat. Istilah bahasa pemrograman tanpa tipe bersifat ambigu. Apakah itu merujuk pada bahasa yang tidak memiliki tipe data atau bahasa yang merupakan varian tanpa tipe kalkulus lambda ?

JavaScript / ECMAScript memiliki sistem tipe dan semua domain fungsinya akan menerima tipe spesifikasi Referensi apa pun. Jadi itu berarti JavaScript memiliki satu tipe data, pada kenyataannya. Itu adalah masalah implementasi yang lebih penting bagi programmer JavaScript yang sangat mahir. Rata-rata programmer JavaScript hanya peduli dengan tipe data bahasa abstrak yang telah ditentukan oleh ECMAScript.

Dalam konteks programmer sehari-hari, bukan peneliti atau ilmuwan komputer teoretis, istilah untyped adalah istilah yang keliru karena kebanyakan orang tidak melakukan lambda kalkulus. Jadi istilah tersebut membingungkan banyak orang dan sepertinya menyatakan bahwa JavaScript tidak memiliki tipe data yang sama sekali tidak benar. Siapapun yang pernah menggunakan typeoftahu bahwa JavaScript memiliki tipe data bahasanya sendiri:

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

hasil

"tali"

ECMAScript mendefinisikan jenis berikut untuk bahasa: undefined, null, string, boolean, number,object

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

Penunjukan yang lebih akurat untuk JavaScript akan diketik secara implisit, diketik secara dinamis, atau diketik dengan lemah / longgar (atau beberapa kombinasinya), di mana JavaScript menggunakan pemaksaan tipe dalam beberapa kasus yang membuat tipe tersirat karena Anda tidak harus secara eksplisit menentukan jenis variabel Anda. Itu berada di bawah ketikan lemah karena, tidak seperti beberapa bahasa yang membedakan antara float dan integer dll, ia hanya menggunakan satu numberjenis untuk mencakup semua angka, dan menggunakan jenis paksaan yang disebutkan sebelumnya [Bagian 9 dari Spesifikasi ECMAScript] , sangat kontras dengan a bahasa yang diketik dengan kuat akan memiliki tipe data yang sangat spesifik (misalnya, Anda harus menentukan intatau float).

Definisi bahasa yang diketik secara statis dan dinamis tidak terstandarisasi, namun begitu juga dengan ukuran byte ketika komputer mulai berkembang. Pengetikan statis dan dinamis paling sering mengacu pada keberadaan fitur bahasa tertentu. Salah satunya adalah pemeriksaan jenis pada waktu proses , atau yang disebut pemeriksaan jenis dinamis . Jika Anda telah menggunakan JavaScript, Anda sudah tahu bahwa itu pasti menunggu hingga waktu proses untuk memeriksa jenis, itulah sebabnya Anda mendapatkan TypeErrorpengecualian selama eksekusi kode Anda. Contoh di sini

Saya pikir jawaban pilihan teratas membingungkan polimorfisme fungsi JavaScript dengan fungsi yang akan menerima apa pun secara harfiah (seperti varian Lambda Calculus yang tidak diketik) yang merupakan Kekeliruan Asosiasi .

Alex W.
sumber
Ini bukan istilah yang salah, tetapi konteks itu penting, lihat stackoverflow.com/questions/9154388/…
Andreas Rossberg
@AndreasRossberg Ini benar - benar keliru. Apa yang Anda rujuk, dalam tautan promosi diri Anda yang tanpa malu-malu , adalah sistem tipe. Alasan istilah ini keliru karena istilah tersebut ambigu. Kebanyakan pemrogram berpikir tipe data bukan tipe sistem ketika mereka mendengar tentang bahasa yang tidak diketik . Saya pikir komentar Konrad Rudoph benar-benar mendorong poin ini.
Alex W
Tidak yakin mengapa Anda merasa "tidak tahu malu" untuk merujuk ke jawaban saya sebelumnya daripada mengulanginya di sini. Juga, saya dengan jelas mengatakan bahwa konteks itu penting. Berbeda dengan keluhan K. Rudolph, ada definisi yang konsisten dan diterima secara luas dari "sistem tipe" dalam literatur, dan saya mengutip salah satunya. Tentu saja, Anda bebas untuk menganggapnya membingungkan dalam konteks Anda, tetapi itu tidak membuat mereka "misnomers".
Andreas Rossberg
@AndreasRossberg Konteks sangat penting di sini. Jawaban pilihan teratas mengatakan "untyped = no type declarations" yang jelas - jelas salah. Apa yang saya katakan adalah bahwa itu adalah istilah yang salah, dalam konteks ini. Tidak ada yang menyebutkan kalkulus lambda di sini dan melakukannya agak berlebihan dalam kasus sederhana ini.
Alex W
1

Ingatlah bahwa JavaScript memungkinkan Anda untuk menanyakan apa itu typeof(your_variable), dan membandingkan tipe: 5==="5"pengembalian false. Jadi saya rasa Anda tidak bisa menyebutnya tanpa tipe.

Ini secara dinamis dan (diperkirakan) diketik dengan lemah. Anda mungkin ingin tahu itu menggunakan pengetikan Bebek (lihat tautan andrew) dan menawarkan OOP melalui Prototyping alih-alih kelas dan warisan.

contoh saya
sumber
Mengetik variabel tidak ada hubungannya dengan pemberian nilai. Ini ada hubungannya dengan deklarasi tipe untuk variabel. Javascript sama sekali tidak memiliki konstruksi untuk ini, itulah sebabnya mengapa sangat sedikit javascripters yang memahami konsep tersebut, dan mengapa begitu banyak dari mereka salah memahami pengetikan variabel sebagai sesuatu yang berkaitan dengan membandingkan atau mentransmisikan jenis variabel. Dalam JS Anda tidak dapat mendeklarasikan String a = "blah";atau var a:String = 'blah';(yaitu variabel yang diketik) sama sekali. Itulah mengapa tidak diketik.
Jimbo Jonny
0

Sementara itu diketik (Anda dapat bertanya "typeof someVar" dan mempelajari jenis spesifiknya, ini sangat lemah.

Diberikan:

  var a = "5";

Anda bisa mengatakan bahwa a adalah string. Namun, jika Anda kemudian menulis:

  var b = a + 10;

b adalah int sama dengan 15, jadi a bertindak seperti int. Tentu saja, Anda kemudian dapat menulis:

  var c = a + "Hello World";

dan c akan sama dengan "5Hello World", jadi a lagi-lagi bertindak seperti string.

James Curran
sumber
1) Casting nilai! = Mengetik variabel 2) tidak lemah, tidak ada. Anda tidak dapat mengetik variabel dalam javascript.
Jimbo Jonny
Penasaran mengapa jawaban ini mendapat dua suara rendah. Definisi yang saya temukan pada pengetikan lemah mengatakan persis seperti ini: Jenis nilai ditentukan berdasarkan cara penggunaannya.
aioobe
Apakah ini akurat? Saya mendapatkan bsederajat 510: ideone.com/BRcSW7
aioobe