JavaScript türlenmemiş bir dil midir?


104

Bazı kişilerin JavaScript'i "dinamik, zayıf yazılmış" bir dil olarak adlandırdığını, ancak bazılarının "türlenmemiş" dediğini fark ettim. Gerçekten hangisi?

Yanıtlar:


133

JavaScript olduğunu türsüz:


(kaynak: no.gd )

Brendan Eich bile öyle diyor. Twitter'da bu soruyla bağlantılı bir konuya cevap verdi:

... akademik türler "statik tür yok" anlamında "türlenmemiş" ifadesini kullanır ...

Yani sorun şu ki, türsüzlüğün birkaç farklı tanımı var .

Yukarıdaki cevaplardan birinde bir tanımdan bahsedilmiştir - çalışma zamanı değerleri etiketlemez ve her bir değeri bit olarak ele alır. JavaScript yapar etiket değerleri ve bu etiketlere göre farklı davranış vardır. Yani JavaScript açıkça bu kategoriye uymuyor.

Diğer tanım Programlama Dili Teorisinden (Brendan'ın bahsettiği akademik şey). Bu alanda, türsüz , her şeyin tek bir türe ait olduğu anlamına gelir .

Neden? Çünkü bir dil, yalnızca türlerin hizalandığını kanıtlayabildiğinde bir program oluşturacaktır (aka Curry-Howard yazışmaları ; türler teoremlerdir, programlar kanıtlardır). Bu, yazılmamış bir dilde şu anlama gelir:

  1. Her zaman bir program oluşturulur
  2. Bu nedenle türler her zaman eşleşir
  3. Bu nedenle, yalnızca bir tür olmalıdır

Yazılmış bir dilin aksine:

  1. Bir program olmayabilir üretilebilir
  2. Türleri Çünkü olmayabilir maç
  3. Çünkü bir program birden çok tür içerebilir

Yani, PLT orada, gitmek türsüz sadece araç dinamik olarak yazılan ve daktilo sadece anlamına gelir statik olarak yazılan . JavaScript kesinlikle bu kategoride yazılmamış.

Ayrıca bakınız:


6
Ve tabii ki, "statik tür yok", "tür bildirimi yok" ile aynı şey değildir.
Andreas Rossberg

+1. Belki bunu cevabınızda da bağlamalısınız . Bu "zayıf yazılmış" bs çok yaygın.
missingfaktor

2
Programlama Dili Teorisi doğrudur. Dev ekran görüntüsü yanlış.
Alex W

2
Bu cevabın Harper'ın blog gönderisine atıfta bulunmasına sevindim, ancak PLT topluluğu "birleştirilmemiş" lehine "türlenmemiş" ifadesini bıraksaydı iyi olurdu. "Tiplenmemiş", "sadece bitler" anlamına gelen tanım aslında anlamlıdır. Biçimsel belirtiminde "tür" kelimesini kullanan ve yedi türü (Tanımlanmamış, Boş, Sayı, Dize, Boolean, Sembol ve Nesne) olduğunu söyleyen bir dili tanımlamak için "türlenmemiş" ifadesini kullanmak gerçekten kafa karıştırıcıdır. Çoğu insan bu tür kavramını PLT def'inden ayırmak istemez.
Ray Toal

4
Sizin 1. 2. 3.için Türlenmemiş dil JavaScript eşleşmiyor. Değil Orada sadece tek tip - yani JavaScript sınıflandırılmamış gösterdiği şey nasıl 5. So - 4 hakkında var?
Don Cheadle

82

güçlü / zayıf , uygunsa, yazmayı nasıl ele aldığına göre düşünülebilir.

  • Zayıf yazılan , varsa derleyicinin doğru yazmayı zorlamadığı anlamına gelir. Örtük derleyici interjeksiyonu olmadan, komut çalışma zamanı sırasında hata verecektir.

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

    Kesinlikle yazdınız orada bir derleyici ve size gelen açık döküm istediği vasıtaları dize kadar tamsayı .

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

    Her iki durumda da, bazı derleyicinin özellikleri, yapılacak doğru şeyin bu olduğunu belirleyebiliyorsa, derleme sırasında sizin için dönüştürme yapmak üzere talimatı dolaylı olarak değiştirebilir.

    Şimdiye kadar, JavaScript Kesinlikle Yazılmamış olarak kategorize edilebilir. Bu, zayıf yazılmış veya yazılmamış olduğu anlamına gelir.

dinamik / statik olabilir dil talimatları türlerini işlemek nasıl ilişkili olarak düşünülebilir.

  • Dinamik olarak yazılmış , değerin türünün zorlandığıanlamına gelir, ancak değişken herhangi bir türden herhangi bir değeri temsil eder.

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

    Statik olarak tür, değişken türünün güçlü bir şekilde uygulandığı ve değer türünün daha az zorlandığıanlamına gelir.

    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.
    

    Şimdiye kadar, JavaScript Statik Olarak Yazılmamış olarak kategorize edilebilir. Ayrıca, yazıldıysa, Dinamik Olarak Yazılmış gibi görünür. Bu yüzden Yazmanın ne anlama geldiğini görmemiz gerekiyor.

Typed , dilin string , number , boolean , object , array , null , undefined vb.Gibi farklı türleri ayırt ettiği anlamına gelir. Ayrıca her işlem belirli türlere bağlıdır. Yani bir tamsayıyı bir dizgeye bölemezsiniz.

    2 / "blah"  // produces NaN

Türlenmemiş aracı bölme işlemi tam sayı ile dize ilk dört bayt tedavi neden olur dize kadar tamsayı . Bunun nedeni, Tiplenmemiş işlemlerin doğrudan bitler üzerinde gerçekleşmesidir, gözlemlenecek tür yoktur. Sonuç, oldukça beklenmedik bir şey olacak:

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

JavaScript, Typed olmanın tanımına göre davrandığından, olması gerekir. Ve bu nedenle Dinamik Olarak Yazılmış ve Zayıf Yazılmış olmalıdır.

Herhangi biri JavaScript'in Tipsiz olduğunu iddia ederse, bu sadece akademik teori içindir, pratik uygulama için değil.


1
Ama son açıklamada bir çelişki olduğunu düşünüyorum. JavaScript'te, bir tamsayı-dizge bölümünün sonucu, tamsayı veya dizenin herhangi bir değeri için iyi tanımlanmıştır. Bu pek kullanışlı değil!
Deniz Doğan

Daha iyi bir tanımınız / tanımınız varsa, onu düzenlemekten çekinmeyin. Bu yüzden topluluk wikisi yaptım.
Gumbo

@skurpur: Dinamik ve Zayıf yazmanın anlamlarını tamamen değiştirdiniz - bunu düzelttiniz.
Rene Saarsoo

Oh, üzgünüm, ben de düzeltirken düzenlediniz ve ben de değişikliklerinizin üzerine yazdım.
Rene Saarsoo

3
-1. Okumayı gerek bu .
missingfaktor

48

JavaScript zayıf yazılmıştır . Kesinlikle "türlenmemiş" değildir, ancak zayıf bir şekilde yazılmış yapısı, örtük dönüştürmeler açısından çok fazla esneklik sağlar.

JavaScript'in de dinamik olarak yazıldığını unutmayın. Bu yazma yöntemi "ördek yazma" olarak bilinen şeye izin verir .

Karşılaştırma için JavaScript'in güçlü bir şekilde yazılmadığını veya statik olarak yazılmadığını göz önünde bulundurun . Bazen bir şeyin ne olmadığını anlamak , onun ne olduğunu daha iyi görmenize yardımcı olabilir.


2
-1. Okumayı gerek bu .
missingfaktor

3
Bu cevap, en çok oylanan cevaptan çok daha iyi ve çok daha doğrudur.
Alex W

3
@JimboJonny: Doğru değil. Bir Assembly geliştirici olmadığı sürece, her dilin daktilo edildiğini söylemek çok da yanlış olmaz. Türsüz, yalnızca işlemlerin doğrudan bit manipülasyonunda olduğu anlamına gelir. Ancak Javascript'in toString () ve parseInt () yöntemleri olduğunu düşünün. Bundan daha fazlasını yazmayın.
Suamere

2
@Suamere - İşte O'Reilly'nin "Javascript: The Definitive Guide" adlı kitabından bir alıntı: "JavaScript ile Java ve C gibi diller arasındaki önemli bir fark, JavaScript'in türsüz olmasıdır. Bu, kısmen, bir JavaScript değişkeninin, yalnızca bildirildiği belirli bir veri türünü tutabilen bir Java veya C değişkeninin aksine, herhangi bir veri türünün değerini tutabileceği anlamına gelir. "
Jimbo Jonny

3
Öyleyse, BS'yi satın alırsanız, bazı ahbap, akademik insanların kasıtlı olarak "tiplenmemiş" kelimesini "dinamik olarak yazılmış" anlamında kullandıklarını iddia eder. O zaman evet, JavaScript tüm provalarınız tarafından tiplenmemiş. Ancak "türlenmemiş" ifadesinin yanlış bir şekilde gerçekten "dinamik olarak yazılmış" dilleri temsil etmek için kullanıldığını biliyorsanız , o zaman dang dillerini "dinamik olarak yazılmış" olarak adlandırın. tinyurl.com/czhcv54
Suamere

8

Yazarın bakış açısına göre JavaScript, Dinamik olarak yazılmış olarak da sınıflandırılmıştır . Wiki, Dinamik olarak yazılan dillerin bir derleyici yerine çalışma zamanında tür denetlendiğini belirtirken, Zayıf Yazılan, kodunuzdaki türü anında değiştirme yeteneğini ifade eder. Yani evet, hem Dinamik olarak hem de Zayıf bir şekilde yazılmıştır.


6

Burada birçok programcının kafasını karıştıran sorun, bunun gibi tanımların bir yerde standartlaştırılmamış olmasıdır. Terimi türsüz programlama dili belirsiz. Bu, veri türü olmayan bir dile mi yoksa lambda analizinin türlenmemiş varyantı olan bir dile mi atıfta bulunuyor ?

JavaScript / ECMAScript bir tür sistemine sahiptir ve tüm işlevlerinin etki alanları herhangi bir Referans belirtim türünü kabul eder. Bu, gerçekte JavaScript'in tek bir veri türüne sahip olduğu anlamına gelir. Bu, çok gelişmiş JavaScript programcıları için daha önemli olan bir uygulama meselesidir. Ortalama bir JavaScript programcısı, yalnızca ECMAScript tarafından belirtilen soyut dil veri türleriyle ilgilenir .

Araştırmacı veya teorik bilgisayar bilimcisi değil, günlük programcı bağlamında, türlenmemiş terimi yanlış bir isimdir çünkü çoğu insan lambda hesabı yapmaz. Bu nedenle terim kitlelerin kafasını karıştırır ve JavaScript'in herhangi bir veri türüne sahip olmadığını belirtir gibi görünür ki bu doğru değildir. Şimdiye kadar kullanmış olan herkes typeof, JavaScript'in kendi dil veri türleri olduğunu bilir:

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

verim

"dize"

ECMAScript dil için aşağıdaki türde tanımlar: undefined, null, string, boolean, number,object

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

JavaScript için daha doğru bir atama örtük olarak yazılır, dinamik olarak yazılır veya zayıf / gevşek yazılır (veya bunların bir kombinasyonu), çünkü JavaScript bazı durumlarda tür zorlamasını kullanır , bu da türü örtük yapar, çünkü açıkça belirtmek zorunda değilsiniz. değişkenlerinizin türü. Zayıf bir şekilde yazılır, çünkü kayan ve tamsayı vb. Arasında ayrım yapan bazı dillerden farklı numberolarak, tüm sayıları kapsamak için yalnızca bir tür kullanır ve daha önce bahsedilen tür zorlamasını kullanır [ECMAScript Spec Bölüm 9] , güçlü bir tezat olarak çok spesifik veri türlerine sahip olan kesin yazılmış dil (yani intveya belirtmeniz gerekir float).

Statik ve dinamik olarak yazılmış dillerin tanımları standartlaştırılmamıştır, ancak bilgisayarlar gelişmeye başladığında bir bayt boyutu da değildi. Statik ve dinamik yazım, çoğunlukla belirli dil özelliklerinin varlığına atıfta bulunur. Bunlardan biri çalışma zamanında tür denetimi veya dinamik tür denetimi denen şeydir . JavaScript kullandıysanız, türleri kontrol etmek için çalışma zamanına kadar kesinlikle beklediğini zaten biliyorsunuzdur, bu nedenle TypeErrorkodunuzun yürütülmesi sırasında istisnalar alırsınız . Örnek burada

Cevabın kafa karıştırıcı En yüksek oyu düşünüyorum JavaScript işlevlerin polimorfizm bir olduğunu tam anlamıyla (Lambda Calculus türsüz varyantları olduğu gibi) her şeyi kabul edecek fonksiyonları ile Ortaklık Fallacy .


Bu bir yanlış isim değil, ancak bağlam önemlidir, bkz. Stackoverflow.com/questions/9154388/…
Andreas Rossberg

@AndreasRossberg Kesinlikle olan bir isim. Ne de, bakın sizin utanmadan kendini terfi bağlantı , bir tür sistemidir. Terimin yanlış isimlendirilmesinin nedeni, belirsiz olmasıdır. Çoğu programcı , türsüz bir dil duyduklarında veri türünün sistem türü olmadığını düşünür . Bence Konrad Rudoph'un yorumu bu noktayı gerçekten eve götürüyor .
Alex W

Burada tekrarlamak yerine önceki cevabıma başvurmayı neden "utanmaz" bulduğundan emin değilim. Ayrıca, bağlamın önemli olduğunu açıkça söyledim. K. Rudolph'un şikayetinin aksine, literatürde "tip sistemi" nin mükemmel bir şekilde tutarlı ve geniş kabul gören tanımları var ve ben bir tanesini aktardım. Elbette, onları bağlamınızda kafa karıştırıcı bulmakta özgürsünüz, ancak bu onları "yanlış adlandırmalar" yapmaz.
Andreas Rossberg

@AndreasRossberg Bağlam burada çok önemlidir. En çok oylanan yanıt, açıkça yanlış olan "türsüz = tür bildirimi yok" diyor . Demek istediğim, bu bağlamda yanlış bir adlandırma olduğudur. Burada hiç kimse lambda hesabından bahsetmedi ve bunu yapmak bu basit durumda biraz iddialı.
Alex W

1

JavaScript'in ne olduğunu sormanıza typeof(your_variable)ve türleri karşılaştırmanıza izin verdiğini unutmayın : 5==="5"dönüşler false. Bu yüzden ona türsüz diyebileceğinizi sanmıyorum.

Dinamik olarak ve (olarak tahmin ediliyor) zayıf yazılmıştır. Ördek yazmayı kullandığını bilmek isteyebilirsiniz (Andrew'un bağlantısına bakın) ve sınıflar ve kalıtım yerine Prototipleme yoluyla OOP sunar .


Bir değişkenin yazılmasının değerlerin çevrimiyle ilgisi yoktur. Değişkenler için tür bildirimleri ile ilgisi vardır. Javascript bunun için hiç bir yapıya sahip değil, bu yüzden çok az sayıda javascripter kavramı anlıyor ve bu yüzden çoğu değişken yazmayı değişken türlerini karşılaştırmak veya dönüştürmekle ilgili bir şey olarak yanlış yorumluyor. JS'de tanımlayamazsınız String a = "blah";veya var a:String = 'blah';(yani yazılan değişkenler) TÜMÜNÜNDE. Bu yüzden tiplenmemiş.
Jimbo Jonny

0

Yazılırken ("typeof someVar" sorabilir ve belirli türünü öğrenebilirsiniz, çok zayıftır.

Verilen:

  var a = "5";

a'nın bir dizge olduğunu söyleyebilirsiniz. Ancak, sonra yazarsanız:

  var b = a + 10;

b, 15'e eşit bir int'dir, bu nedenle a, int gibi davranır. Tabii ki, sonra yazabilirsiniz:

  var c = a + "Hello World";

ve c "5Hello World" e eşit olacaktır, yani a yine bir dizge gibi davranır.


1) Bir değer atamak! = Bir değişken yazmak 2) zayıf değil, yok. JavaScript'te bir değişken yazamazsınız.
Jimbo Jonny

Bu cevabın neden iki olumsuz oy aldığını merak ediyorum. Zayıf yazmada bulduğum tanım tam olarak şunu söylüyor: Bir değerin türü, nasıl kullanıldığına göre belirlenir.
aioobe

Bu doğru mu? Ben olsun beşittir 510: ideone.com/BRcSW7
aioobe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.