JavaScript motorları başlangıçta yalnızca web tarayıcılarında kullanılıyordu, ancak günümüzde bazısunucuların ve çeşitliuygulamaların da temel bileşenleridir. Bu kullanım için en yaygın çalışma zamanı sistemiNode.js'dir.
Java ve JavaScript'in ad,sözdizimi ve ilgilistandart kitaplıklar açısından benzerlikleri olsa da, iki dil birbirinden farklıdır ve tasarım açısından da büyük farklılıklar gösterir.
Grafik kullanıcı arayüzüne sahip ilkweb tarayıcısıMosaic, 1993 yılında piyasaya sürüldü. Teknik bilgisi olmayan kişilerin erişebildiği, yeni ortaya çıkanWorld Wide Web'in hızlı büyümesinde önemli bir rol oynamıştır.[15] Mosaic'in önde gelen geliştiricileri daha sonra 1994'te daha parlak bir geleceği olduğu düşünülenNetscape Navigator tarayıcısını piyasaya sürenNetscape şirketini kurdular. Netscape Navigator hızla en çok kullanılan tarayıcı haline geldi.[16][17]
Web'in yeni şekillenmeye başladığı bu yıllarda,web sayfaları yalnızca statik olabilirdi ve sayfa tarayıcıya yüklendikten sonra dinamik davranış yeteneğinden de yoksundu. Gelişen web geliştirme sahnesinde, programlamacıların bu sınırlamanın kaldırılmasına yönelik istekleri vardı, bu nedenle 1995'te Netscape, Navigator'a birkomut dosyası dili eklemeye karar verdi. Bunu başarmak için iki yol izlediler:Javaprogramlama dilini yerleştirmek içinSun Microsystems ile iş birliği yaparken, aynı zamandaScheme dilini yerleştirmek için deBrendan Eich'i işe aldılar.[5]
Netscape yönetimi kısa süre sonra Eich için en iyi seçeneğin Java'ya benzer ve daha az Scheme veya diğer mevcut komut dosyası dillerine benzeyen yeni bir dil tasarlamak olduğuna karar verdi.[5] Eylül 1995'te Navigatorbeta'nın bir parçası olarak ilk sunulduğunda, eklenen yeni dil veyorumlayıcı uygulaması LiveScript olarak adlandırılsa da, Aralık ayında resmi sürüm için adı JavaScript olarak değiştirildi.[5][18]
JavaScript adının seçimi, doğrudan Java ile ilgili olduğu imâ edilerek kafa karışıklığına neden oldu. O zamanlardot-com balonu patlamıştı ve Java henüz yeni bir programlama dili idi, bu nedenle Eich, JavaScript adını Netscape'in bir pazarlama taktiği olarak gördü.[19]
JScript ilk olarak 1996'da,CSS için ilk veHTML uzantıları ile birlikte piyasaya sürüldü. Bu uygulamaların her biri, Navigator'daki benzerlerinden belirgin şekilde farklıydı.[21][22] Bu farklılıklar, geliştiricilerin web sitelerinin her iki tarayıcıda da sağlıklı şekilde çalışmasını zorlaştırdı ve birkaç yıl boyunca "En iyi Netscape'te görüntülenir" ve "En iyi Internet Explorer'da görüntülenir" şeklinde logoların yaygın olarak kullanılmasına yol açtı.[21][23]
Kasım 1996'daNetscape, JavaScript'iEcma International'a tüm tarayıcı satıcılarının uyabileceği standart bir belirtimin başlangıç noktası olarak sundu. Bu, Haziran 1997'de ilkECMAScript dil spesifikasyonunun resmî olarak yayınlanmasına yol açtı.
Standartlar süreci, ECMAScript 2'nin Haziran 1998'de ve ECMAScript 3'ün Aralık 1999'da piyasaya sürülmesiyle birkaç yıl boyunca devam etti. ECMAScript 4 üzerindeki çalışmalar ise 2000 yılında başladı.[20]
Bu aradaMicrosoft, tarayıcı pazarında giderek daha baskın bir konuma geldi. 2000'lerin başında, Internet Explorer'ın pazar payı %95'e ulaştı.[24] Bu durum,JScript'in Web'deistemci tarafı komut dosyası oluşturmak için gerçek bir standart haline geldiği anlamını taşıyordu.
Microsoft başlangıçta standartlar sürecine katıldı ve bazı önerileri kendi JScript dilinde uyguladı, ancak sonunda Ecma çalışması üzerinde iş birliğini durdurdu. Böylece ECMAScript 4 yenilmiş oldu.
2000'lerin başındaInternet Explorer'ın hakimiyeti döneminde, istemci tarafı komut dosyası oluşturma yöntemi oldukça durgundu. Bu, Netscape'in halefiMozilla'nınFirefox tarayıcısını piyasaya sürdüğü 2004 yılında değişmeye başladı. Firefox birçok kişi tarafından iyi bir şekilde karşılandı ve Internet Explorer'dan önemli bir pazar payını kendisine aldı.[25]
2005 yılında Mozilla, ECMA International'a katıldı veECMAScript for XML (E4X) standardı üzerinde çalışmaya başladı. Bu, Mozilla'nın bir ECMAScript 4 taslağına dayanan ActionScript 3 dilinde E4X'i uygulayanMacromedia (daha sonraAdobe Systems tarafından satın alındı) ile ortak olarak çalışmasına yol açtı. Hedef, ActionScript 3'ü yeni ECMAScript 4 olarak standart hale getirmekti. Bu amaçla Adobe Systems,Tamarin uygulamasınıaçık kaynaklı bir proje olarak yayınladı. Ancak, Tamarin ve ActionScript 3, yerleşik istemci tarafı komut dosyası oluşturmaktan çok farklıydı veMicrosoft'un iş birliği olmadan, ECMAScript 4 hiçbir zaman istenen sonuçları vermedi.
Bu arada, ECMA çalışmasına bağlı olmayan açık kaynak topluluklarında çok önemli gelişmeler yaşanıyordu. 2005'teJesse James Garrett,Ajax terimini türettiği ve verilerin arka planda yüklenebileceğiweb uygulamaları oluşturmak için JavaScript'in omurgası olduğu bir dizi teknolojiyi tanımladığı ve tam sayfa gereksinimini ortadan kaldırdığı bir WhiteBook yayınladı. Bu, açık kaynak kitaplıkların ve onların etrafında oluşan toplulukların öncülük ettiği bir JavaScript rönesans dönemini ateşledi.jQuery,Prototype,Dojo Toolkit veMooTools dâhil olmak üzere birçok yeni kitaplık oluşturuldu.
Google,Chrome tarayıcısını 2008'de rakiplerinden daha hızlı olanV8 JavaScript motoruyla piyasaya sürdü.[26][27] En önemli yenilik tamzamanında derlemeydi (JIT),[28] bu nedenle diğer tarayıcı satıcılarının motorlarını JIT için elden geçirmeleri gerekiyordu.[29]
Temmuz 2008'de, bu farklı taraflarOslo'da bir konferans için bir araya geldi. Bu birleşme, konuyla ilgili tüm çalışmaları birleştirmek ve dili ileriye taşımak için 2009 başlarında nihai anlaşmaya yol açtı. Sonucu ise Aralık 2009'da yayınlanan ECMAScript 5 standardıydı.
Dil üzerinde iddialı çalışmalar birkaç yıl boyunca devam etti ve 2015 yılındaECMAScript 6'nın yayınlanmasıyla resmîleştirilen kapsamlı bir ekleme ve iyileştirme derlemesiyle sonuçlandı.[30]
Node.js'nin 2009 yılındaRyan Dahl tarafından oluşturulması, JavaScript'in web tarayıcıları dışında kullanımında önemli bir artışa yol açtı. Node,V8 motorunu, birolay döngüsünü veI/OAPI'lerini birleştirerek bağımsız bir JavaScript çalışma zamanı sistemi sağlamaktaydı. 2018 itibarıyla, Node milyonlarca geliştirici tarafından kullanılıyordu[31] venpm dünyadaki herhangi birpaket yöneticisinden çok daha fazla modüle sahipti.[32]
ECMAScript taslak belirtimi şu andaGitHub'da herkese açık bir şekilde korunmaktadır ve sürümler düzenli şekilde yıllık anlık görüntüler aracılığıyla üretilmektedir.[33] Dildeki olası revizyonlar, kapsamlı bir teklif süreciyle incelenir.[34][35] Artık, sürüm numaraları yerine geliştiriciler, gelecek özelliklerin durumunu tek tek kontrol etmektedirler.[33]
Mevcut JavaScript ekosisteminde bulunan birçokkitaplık veçerçevenin, bazıları yerleşik programlama uygulamaları ve web tarayıcılarının dışında JavaScript'in farklı kullanım alanları için oluşturulmuştur. Ayrıca,tek sayfalık uygulamaların ve diğer JavaScript ağırlıklı web sitelerinin artmasıyla birlikte, geliştirme sürecine yardımcı olmak için birkaçaktarıcı da oluşturulmuştur.[36]
JavaScript,web sitelerinin % 97'sinin bu amaçla kullandığı, Web'in baskınistemci tarafı komut dosyası dilidir.[12] Komut dosyalarıHTML belgelerine gömülür veya bunlar da dâhil edilmiş olur. Böylelikle kodlarDOM ile etkileşime girer. Tüm büyükweb tarayıcılarında, kodu kullanıcının cihazında yürüten yerleşik birJavaScript motoru bulunur.
Kullanıcının davranışıyla ilgili verilerin günlüğe kaydedilmesi ve ardından bir sunucuya gönderilmesi. Web sitesi sahibi bu verilerianaliz,reklam takibi vekişiselleştirme için kullanabilir.
Web sitelerinin %80'inden fazlası, istemci tarafı komut dosyası oluşturma için bir üçüncü taraf JavaScriptkitaplığı veyaweb çerçevesi kullanırlar.[13]
jQuery, web sitelerinin %75'inden fazlası tarafından kullanılan açık ara en popüler kitaplıktır.[13]Facebook, web sitesi içinReact kitaplığını oluşturdu ve daha sonra bunuaçık kaynak olarak yayınladı;Twitter dâhil diğer pek çok site günümüzde bunu kullanmaktadır. Aynı şekildeGoogle'ınYouTube veGmail'i de dâhil olmak üzere web siteleri için oluşturduğuAngular çerçevesi artık başkaları tarafından kullanılabilen açık kaynaklı bir projedir.[13]
Buna karşılık, "Vanilla JS" terimi, herhangi bir kitaplık veya çerçeve kullanmayan, bunun yerine tamamen standart JavaScript işlevselliğine dayanan web siteleri için oluşturulmuştur.[39]
JavaScript,C'ninyapılandırılmış programlama sözdiziminin çoğunu destekler (örneğin,if ifadeleri,while döngüleri,switch ifadeleri,do while döngüleri vb.). Kısmi bir istisnakapsam belirlemedir: başlangıçta JavaScript yalnızcavar ileişlev kapsamına sahipti; daha sonra ECMAScript 2015'telet veconst anahtar sözcükleriyle blok kapsamı eklendi. C gibi, JavaScript deexpressionslar vestatementslar arasında bir ayrım yapar. C'den bir sözdizimsel farkı da, noktalı virgüllerin (deyimleri sonlandıran) atlanmasına izin verenotomatik noktalı virgül eklemedir.[48]
JavaScriptzayıf yazılmıştır, bu kullanılan işleme bağlı olarak belirli türlerin dolaylı olarak yayınlandığı anlamına gelir.[49]
İkili+ operatörü, her iki işlenen de sayı olmadığı sürece her iki işleneni de bir dizeye atar. Bunun nedeni, toplama operatörünün bir birleştirme operatörü olarak da kullanılmasından dolayıdır.
İkili- işleci her zaman her iki işleneni de bir sayıya atar
Her iki birli operatör (+,-) işleneni her zaman bir sayıya çevirir.
Değerler aşağıdaki gibi dizgelere dönüştürülür:[49]
Dizeler olduğu gibi bırakılır
Sayılar dize temsillerine dönüştürülür
Dizilerin öğeleri dizelere dönüştürülür ve ardından virgül (,) ile birleştirilirler.
Diğer objeler[object Object] dizesine dönüştürülür; buradaObject, objenin yapıcısının adıdır
Değerler, dizelere dönüştürülerek ve ardından dizeler de sayılara dönüştürülerek, sayılara dönüştürülür. Bu süreçler, sırasıyla dize ve sayı dökümü için prototip üzerindetoString vevalueOf işlevleri tanımlanarak değiştirilebilir.
JavaScript, kuralların karmaşıklığı tutarsızlıkla karıştırılabileceğinden, bu dönüşümleri uygulama şekli nedeniyle eleştiriler almıştır.[49][50] Örneğin, bir dizeye sayı eklerken, sayı birleştirme yapılmadan önce bir dizeye dönüştürülür, ancak bir dizeden bir sayı çıkarılırken, çıkarma işlemi yapılmadan önce dize bir sayıya dönüştürülür.
Genellikle,{} + [] ile sonuçlanan0 (sayı) da belirtilir. Bu yanıltıcıdır:{} boş bir obje yerine boş bir kod bloğu olarak yorumlanır ve boş dizi kalan unary (tekli)+ operatörü tarafından bir sayıya dönüştürülür. İfadeyi parantez içine alırsanız({} + []) küme parantezleri boş bir obje olarak yorumlanır ve ifadenin sonucu beklendiği gibi"[object Object]" olur.[49]
JavaScript'teki prototip kalıtım,Douglas Crockford tarafından şu şekilde tanımlanır: EKSİK ALANJavaScript'te birobje, bir prototiple büyütülmüş birilişkisel dizidir (aşağıya bakın); her anahtar bir objeninözelliği için ad sağlar ve böyle bir adı belirtmenin iki sözdizimsel yolu vardır: nokta notasyonu (obj.x = 10) ve parantez gösterimi (obj['x'] = 10). Bir özellik, çalışma zamanında eklenebilir, geri tepebilir veya silinebilir. Bir objenin çoğuözelliği (ve bir objenin prototip miras zincirine ait olan herhangi bir özellik), birfor...in döngüsü kullanılarak numaralandırılabilir.
Prototipler
JavaScript, diğer birçok nesne yönelimli dilinkalıtım içinsınıfları kullandığıprototipleri kullanır.[53] JavaScript'te prototiplerle birçok sınıf tabanlı özelliği simüle etmek mümkündür.[54]
Obje oluşturucu olarak fonksiyonlar
Fonksiyonlar, tipik rolleriyle birlikte obje oluşturucular olarak ikiye ayrılır. Bir fonksiyon çağrısınanew ile önek eklemek, yapıcıdan özellikleri ve yöntemleri (Object prototipinden özellikler dâhil) devralan bir prototip örneği oluşturur.[55] ECMAScript 5,Object prototipinden otomatik olarak miras alınmadan bir örneğin açık bir şekilde oluşturulmasına izin verenObject.create yöntemini sunar (eski ortamlar prototipinull öğesine atayabilir).[56]prototype özelliği, yeni objenin dâhili prototipi için kullanılan objeyi belirler. Yapıcı olarak kullanılan fonksiyonun prototipi değiştirilerek yeni yöntemler eklenebilir. JavaScript'inArray veyaObject gibi yerleşik oluşturucuları da değiştirilebilen prototiplere sahiptir.Object prototipini değiştirmek mümkün olsa da, JavaScript'teki çoğu obje,Object prototipinden yöntemleri ve özellikleri devralacağından ve prototipin değiştirilmesini beklemeyebileceğinden, genellikle kötü uygulama olarak kabul edilirler.[57]
Metod olarak fonksiyonlar
Birçok nesne yönelimli dilden farklı olarak, işlev tanımı ilemetot tanımı arasında bir ayrım yoktur. Bunun yerine, fonksiyon çağrısı sırasında ayrım oluşur; Bir fonksiyon, bir objenin metodu olarak çağrıldığında, fonksiyonun yerelthis anahtar sözcüğü, o çağrı için o objeye bağlanır.
Birfonksiyonbirinci sınıftır ; bir fonksiyon bir obje olarak kabul edilir.[58] Bu nedenle, bir fonksiyonun.call() ve.bind() gibi özellikleri ve metotları olabilir.[59]İç içe fonksiyon, başka bir fonksiyon içinde tanımlanan bir fonksiyondur. Dış fonksiyon her çağrıldığında oluşturulur. Ek olarak, iç içe geçmiş her işlevsözcüksel bir kapanış oluşturur: dış işlevinsözcüksel kapsamı (herhangi bir sabit, yerel değişken veya bağımsız değişken değeri dâhil), dış işlevin yürütülmesi sona erdikten sonra bile, her bir iç fonksiyon objesinin iç durumunun bir parçası haline gelir. .[52] JavaScript ayrıcaanonim işlevleri de destekler.
Rol olarak fonksiyonlar [Özellikler (Traits) ve Karışımlar (Mixins)]
JavaScript,Traits[60] veMixins gibiRol modellerinin çeşitli fonksiyon tabanlı uygulamalarını da yerel olarak destekler. Böyle bir fonksiyon,function gövdesi içindethis anahtar sözcüğüne bağlı en az bir yöntemle ek davranışı tanımlar. Daha sonra bir Rol,call yoluyla açıkça devredilmeli veya prototip zinciri aracılığıyla paylaşılmayan ek davranışlara sahip olması gereken objelereapply (uygulama) edilmelidir.
Obje kompozisyonu ve kalıtım
Açık fonksiyon tabanlı yetkilendirme JavaScript'tekompozisyonu kapsarken, örtük yetkilendirme, örneğin, bir objeyle ilgili olabilecek ancak doğrudan bir objeye ait olmayan bir metot bulmak için prototip zinciri her yürüdüğünde zaten gerçekleşir. Metot bulunduğunda, bu objenin bağlamında çağrılır. Bu nedenle JavaScript'tekikalıtım, yapıcı fonksiyonların prototip özelliğine bağlı bir yetkilendirme otomatizmi tarafından kapsanır.
JavaScript, komut dosyalarının ortamla etkileşime girebileceği objeler ve metotlar (örneğin, bir web sayfasıDOM u) sağlamak için tipik olarak bir çalışma zamanı ortamına (örneğin birweb tarayıcısı ) dayanır. Bu ortamlar tekiş parçacıklıdır . JavaScript ayrıca, komut dosyalarını (örneğin,HTML<script> öğeleri) dahil etme/içe aktarma yeteneği sağlamak için çalışma zamanı ortamına da güvenir. Bu, başlı başına bir dil özelliği değildir, ancak çoğu JavaScript uygulamasında yaygındır. JavaScript, birkuyruktan gelenmesajları birer birer işler. JavaScript, her yeni mesajla ilişkili birfonksiyonu çağırır ve fonksiyonunbağımsız değişkenleri veyerel değişkenlerle birçağrı yığını (call stack) çerçevesi oluşturur. Çağrı yığını, fonksiyonun ihtiyaçlarına göre küçülür veya büyür. Fonksiyon tamamlandıktan sonra çağrı yığını boş olduğunda, JavaScript sıradaki bir sonraki mesaja ilerler. Bunaolay döngüsü (event loop) denir ve "tamamlanmak için çalıştır" olarak tanımlanır, çünkü her mesaj bir sonraki mesaj dikkate alınmadan önce tamamen işlenir. Ancak, dilineşzamanlılık modeli, olay döngüsünüengellemeyen olarak tanımlar: programgirişi/çıkışı,olaylar vegeri arama işlevleri (callback fonksiyon) kullanılarak gerçekleştirilir. Bu, JavaScript'in bir veritabanı sorgusunun bilgi döndürmesini beklerken bir fare tıklamasını işleyebileceği anlamına gelir.[61]
Değişken (Varyadik) fonksiyonlar
Bir fonksiyona sınırsız sayıda parametre iletilebilir. Fonksiyon bunlarabiçimsel parametreler aracılığıyla ve ayrıca yerelarguments objesi aracılığıyla erişebilir.bind yöntemi kullanılarakdeğişken fonksiyonlar da oluşturulabilir.
Dizi ve obje değişmezleri (literal)
Birçok komut dosyası dili gibi, diziler ve objeler (diğer dillerdekiilişkisel diziler ) kısa bir kısayol sözdizimi ile oluşturulabilir. Aslında, budeğişmez değerlerJSON veri formatının temelini oluşturur.
Düzenli ifadeler (Regular expressions)
JavaScript ayrıca, yerleşik dize işlevlerinden daha karmaşık olan metin işleme için özlü ve güçlü bir sözdizimi sağlayanPerl'e benzer şekildedüzenli ifadeleri de destekler.[62]
Sözler (Promise) ve zaman uyumsuz/bekleme (Async/await)
JavaScript, zaman uyumsuz işlemleri işlemek içinpromise ları veAsync/await destekler. Yerleşik bir Promise objesi, vaatleri işlemek ve işleyicileri eşzamansız bir eylemin nihai sonucuyla ilişkilendirmek için işlevsellik sağlar. Son zamanlarda, geliştiricilerin birden çok JavaScript promise ını birleştirmesine ve farklı senaryolara dayalı işlemler yapmasına olanak tanıyan JavaScript belirtiminde birleştirici yöntemler tanıtıldı. Tanıtılan yöntemler şunlardır: Promise.race, Promise.all, Promise.allSettled ve Promise.any. Zaman uyumsuz/bekleme, eşzamansız, engellemesiz bir işlevin sıradan bir eşzamanlı işleve benzer bir şekilde yapılandırılmasına izin verir. Asenkron, bloke edici olmayan kod, minimum ek yük ile geleneksel senkronize, bloke edici koda benzer şekilde yapılandırılabilir.
JavaScript'tekideğişkenler,var,[64]let[65] veyaconst[66] anahtar sözcükleri kullanılarak tanımlanabilir.
// 'x' adında bir fonksiyon kapsamlı (function-scoped) değişken bildirir ve buna üstü kapalı şekilde// 'undefined' özel değerini atar. Değeri olmayan değişkenler otomatik 'undefined' (tanımsız) olarak ayarlanır.varx;// Değişkenler, bunun gibi elle 'tanımsız' olarak ayarlanabilirvarx2=undefined;// Örnek `y` adında bir değişkeni blok kapsamında (block-scoped) bildirir ve// değişkenin bir değeri olmadığı için onu `undefined` (tanımsız) olarak ayarlar.// "let" anahtar sözcüğü ECMAScript 2015'te tanıtılmıştır.lety;// Blok kapsamında (block-scoped) bir bildirim yapar, `z` artık yeniden değer atanamaz olur ve// onu bir string değişmezine ayarlar. `const` anahtar sözcüğü ECMAScript 2015'te tanıtılmıştır ve// yalnızca net bir şekilde atanır.// `const` anahtar sözcüğü 'sabit' anlamına gelir ki bu nedenden dolayı 'değeri' (value) sabit olduğundan// değişken bazı ufak istisnalar dışında yeni değer alamaz/atanamaz.constz="bu anahtar sözcüğünün değeri yani buraya yeniden atama yapılamaz!";// `benimSayim` isimli bir değişken bildirilmiş ve değer (value) olarak ona bir sayı değişmezi// örneğimizde `2`) atanmıştır.letbenimSayim=2;// `benimSayim` ı yeniden atar ve onun değerini bir dizi değişmezi (örneğimizde `"bir şeyler"`) atar.// JavaScript dinamik olarak yazılmış bir dildir, bu nedenle bu yönergelerine uygundur.benimSayim="bir şeyler";
Yukarıdaki örnekte, hepsinin önünde ikieğik çizgi bulunanyorumlara dikkat edin.JavaScript'te yerleşikGiriş/Çıkış (I/O) işlevi yoktur; çalışma zamanı ortamı bunu sağlar. Sürüm 5.1'deki ECMAScript belirtimi şunları belirtir:[67]
aslında, bu spesifikasyonda harici veri girişi veya hesaplanan sonuçların çıkışı için herhangi bir şart yoktur.
Ancak, çoğu çalışma zamanı ortamında çıktı yazdırmak için kullanılabilecek birconsole objesi[68] bulunur. İşte JavaScript'te minimalist birHello World programı :
console.log("Merhaba, Dünya!");
HTML belgelerinde bir çıktı için bu program gereklidir:
// "write" metodu kullanılarak, metin nodu (düğümü) yazılabilir.document.write('bir şeyler');// HTML elementleri de oluşturulabilir. Öncelikle DOM üzerinde oluşturulmaları gerekirconstbenimElementim=document.createElement('div');// Class veya id gibi öznitelikler oluşturulabilir.benimElementim.classList.add('bir-seyler');// benimElementim.classList.add("anotherclass");benimElementim.id='baska-seyler';// Burada, öznitelik şöyle görünecektir: <span data-attr="baz"></span>benimElementim.setAttribute('data-atrr','baz');// Son olarak, onu HTML'deki <body> öğesine bir alt öğe olarak ekleyindocument.body.appendChild(benimElementim);// Elementler bir öğe olarak querySelector ile yakalanabilir ya da forEach döngüsü ile alınabilen birden çok öğe querySelectorAll ile yakalanabilir.document.querySelector('.class');document.querySelector('#id');document.querySelector('[data-other]');document.querySelectorAll('.multiple');
ya da aşağıdaki örnekte olduğu gibi faktöriyel hesaplamasını kontroller ve üçlü operatör vasıtasıyla da kullanabilirsiniz.
functionfaktoriyel(n){// Yalnızca pozitif bir sayı kullanılmasına izin verin yoksa konsolda uyarı gösterin.if(isNaN(n)){console.error("Sayısal olmayan argümana izin verilmemektedir.");returnNaN;// bu özel bir değerdir ve "Bu Bir Sayı Değil" anlamına gelir.}if(n===0)return1;// 0! = 1if(n<0)returnundefined;// Negatif sayılar değer olarak verildiğinde 'tanımsız' bildirimi yapın .if(n%1){console.warn(`Belirttiğiniz${n} ondalıklı değeri en yakın tam sayıya yuvarlanacaktır. Tam sayı olmayanlar için bunun yerine gamma fonksiyonunu kullanmayı düşünün.`);n=Math.round(n);}// Yukarıdaki kontrolleri kullanmak istemeyebilirsiniz. Zorunlu değildir. Bu kısımdan sonra gerçek özyinelemeli faktoriyel hesaplama kodları yer almaktadır.// Aşağıdaki satırda özyinelemeleli faktöriyel hesaplamada kullanılan fonksiyon ifadesidir. ES6 ile birlikte tanıtımı yapılan ok fonksiyon söz dizimini kullanır.constozyinelemeli_hesaplama=a=>a>1?a*ozyinelemeli_hesaplama(a-1):1;// '?' ile birlikte üçlü operatör kullanımına dikkat ediniz.returnozyinelemeli_hesaplama(n);}document.write(faktoriyel(3));// 6 döndürür
letisimsizFonksiyon=()=>console.log("İsimsiz bir fonksiyon");isimsizFonksiyon();// "İsimsiz bir fonksiyon" yazısını konsola getirir.
Bu örnek, JavaScript'tefonksiyon kapanışlarının yerel olmayan değişkenlerini başvuru yoluyla yakaladığını gösterir.
Ok işlevleri ilk olarak6. Baskı - ECMAScript 2015'te tanıtıldı. JavaScript'te işlev yazmak için sözdizimini kısaltırlar. Ok işlevleri anonimdir, bu nedenle oluşturulduktan sonra onları çağırmak için bunlara başvurmak için bir değişken gerekir.
Ok işlevi (arrow fonksiyon) örneği:
// Ok fonksiyonları (arrow functions) `function` anahtar sözcüğünü kullanmadan// fonskiyon yazmamıza izin verir.// Buradaki `uzun_ornek` bir anonymous function value sunu gösterir.constuzun_ornek=(giris1,giris2)=>{console.log("Merhaba, Dünya!");constcikti=giris1+giris2;returncikti;};// Parantez yoksa, ok fonksiyonu yalnızca ifadeyi (expression) döndürür// Buradaki gibi (giris1 + giris2)constkisa_ornek=(giris1,giris2)=>giris1+giris2;console.log(kisa_ornek(2,3));// 5 döndürür ve ardından "Merhaba, Dünya!" yazdırırconsole.log(uzun_ornek(2,5));// 7 döndürür// Bir ok fonksiyonunun yalnızca bir parametresi varsa, parantezler kaldırılabilir.constparantezsiz=giris=>giris+2;console.log(parantezsiz(3));// 5 döndürür
JavaScript'teobjeler, fonskiyonlarla aynı şekilde oluşturulur; bu nedenle ojbeler birfonksiyon objesi olarak bilinirler.
Obje örneği:
letkullanici={adi:"Ahmet",yasi:41,selamVer(){// "this" burada "mevcut obje" diralert(this.adi);}};kullanici.selamVer();// Ahmet
Anında çağrılan fonksiyon ifadeleri genellikle kapanışları (closures) oluşturmak için kullanılır. Kapanışlar, özelliklerin (properties) ve metotların bir ad alanında (namespace) toplanmasına ve bazılarının özel hale getirilmesine izin verir:
letsayac=(function(){leti=0;// özel özellikreturn{// genel metotlarget:function(){alert(i);},set:function(deger){i=deger;},artir:function(){alert(++i);}};})();// modülsayac.get();// 0 gösterirsayac.set(6);sayac.artir();// 7 gösterirsayac.artir();// 8 gösterir
/* mymodule.js */// Bu fonksiyon (işlev), dışa aktarılmadığı için özel olarak kalırlettopla=(a,b)=>{returna+b;}// Değişkenleri dışa aktarexportletadi='Metin';exportletyasi=23;// Değişkenleri adlarıyla/adlandırılmış olarak dışa aktarexportfunctionekle(sayi1,sayi2){returnsayi1+sayi2;}// Class (sınıfın) dışa aktarılmasıexportclassCarpma{constructor(sayi1,sayi2){this.sayi1=sayi1;this.sayi2=sayi2;}ekle(){returntopla(this.sayi1,this.sayi2);}}
İmport örneği:
// Bir özelliği içe dâhil etme/içe aktarmaimport{ekle}from'./mymodule.js';console.log(ekle(1,2));//> 3// Çoklu şekilde özellikleri içe dahil etme/içe aktarmaimport{adi,yasi}from'./mymodule.js';console.log(adi,yasi);//> "Metin", 23// Bir modüldeki tüm özellikleri dahil etme/içe aktarmaimport*from'./module.js'console.log(adi,yasi);//> "Metin", 23console.log(ekle(1,2));//> 3
/* İki sayının en küçük ortak katını (LCM) bulur */functionLCMCalculator(x,y){// yapıcı/kurucu fonksiyonif(isNaN(x*y))thrownewTypeError("Sayısal olmayan bağımsız değişkenlere izin verilmemektedir.");constcheckInt=function(x){// iç fonksiyonif(x%1!==0)thrownewTypeError(x+" bir tam sayı değil");returnx;};this.a=checkInt(x)// noktalı virgül kullanımı ^^^^ isteğe bağlıdır, yeni satır yeterlidirthis.b=checkInt(y);}// Bir yapıcı/kurucu tarafından oluşturulan obje örneklerinin prototipi,// o yapıcı/kurucunun "prototip" özelliğidir.LCMCalculator.prototype={// obje değişmeziconstructor:LCMCalculator,// bir prototipi yeniden atarken, yapıcı/kurucu özelliğini uygun şekilde ayarlayıngcd:function(){// en büyük ortak böleni hesaplayan yöntem// EÖklid algoritması:leta=Math.abs(this.a),b=Math.abs(this.b),t;if(a<b){// değişkenlerin takas edilmesi// t = b; b = a; a = t;[a,b]=[b,a];// destructuring (yıkım) atamasını kullanarak takas (ES6)}while(b!==0){t=b;b=a%b;a=t;}// Ortak Böleni (GCD) yalnızca bir kez hesaplamanız gerekir, bu nedenle bu yöntemi "yeniden tanımlayın".// (Aslında yeniden tanımlama değildir - örneğin kendisinde tanımlanır,// böylece this.gcd, LCMCalculator.prototype.gcd yerine bu "yeniden// tanımlamaya" atıfta bulunur.)// LCMCalculator obje üyeleri "a" ve/veya "b" sonradan değiştirilirse// bunun yanlış bir sonuca yol açacağını unutmayın.// Ayrıca, 'gcd' === "gcd", this['gcd'] === this.gcdthis['gcd']=function(){returna;};returna;},// Obje/Nesne özellik adları, çift (") veya tek (') tırnak ile sınırlanan stringler ile belirtilebilir."lcm":function(){// Değişken adları nesne/obje özellikleriyle çakışmaz, örneğin |lcm|, |this.lcm| değildir.// FP hassas sorunlarından kaçınmak için |this.a*this.b| şeklinde kullanmıyoruzletlcm=this.a/this.gcd()*this.b;// lcm'yi yalnızca bir kez hesaplamanız gerekir, bu nedenle bu metodu "yeniden tanımlayın".this.lcm=function(){returnlcm;};returnlcm;},// Metotlar ayrıca es6 sözdizimi kullanılarak da bildirilebilirtoString(){// Değerleri birleştirmek için hem es6 şablon değişmezlerini// hem de (+) operatörünü kullanmareturn`LCMCalculator: a =${this.a}, b = `+this.b;}};// Genel çıktı fonksiyonu tanımlayın; bu uygulama yalnızca Web tarayıcıları için çalışırfunctionoutput(x){document.body.appendChild(document.createTextNode(x));document.body.appendChild(document.createElement('br'));}// Not: Dizilerin (array) map() ve forEach() metotları, JavaScript 1.6'da tanımlanmıştır.// Burada JavaScript'in doğal fonksiyonel/işlevsel yapısını göstermek için kullanılırlar.[[25,55],[21,56],[22,58],[28,56]].map(function(pair){// array literal (dizi değişmezi) + mapping function (map/eşleme fonksiyonu)returnnewLCMCalculator(pair[0],pair[1]);}).sort((a,b)=>a.lcm()-b.lcm())// bu karşılaştırmalı fonksiyonla sıralama yapın; =>, "ok fonksiyonu" bir fonksiyonun kısa biçimidir..forEach(printResult);functionprintResult(obj){output(obj+", gcd = "+obj.gcd()+", lcm = "+obj.lcm());}
Tarayıcı penceresinde aşağıdaki çıktı görüntülenmelidir.
LCMCalculator: a = 28, b = 56, gcd = 28, lcm = 56LCMCalculator: a = 21, b = 56, gcd = 7, lcm = 168LCMCalculator: a = 25, b = 55, gcd = 5, lcm = 275LCMCalculator: a = 22, b = 58, gcd = 2, lcm = 638
JavaScript veDOM, kötü niyetli yazarlara Web aracılığıyla bir istemci bilgisayarda çalıştırılacak komut dosyaları sunma potansiyeli sağlar. Tarayıcı yazarları, iki kısıtlama kullanarak bu riski en aza indirir. İlk olarak, komut dosyaları, dosya oluşturma gibi genel amaçlı programlama görevlerini değil, yalnızca Web ile ilgili eylemleri gerçekleştirebilecekleri birsanal alanda çalışır. İkinci olarak, komut dosyalarıaynı kaynak ilkesiyle sınırlandırılmıştır: bir Web sitesindeki komut dosyaları, başka bir siteye gönderilen kullanıcı adları, parolalar veya tanımlama bilgileri gibi bilgilere erişemez. JavaScript ile ilgili güvenlik hatalarının çoğu, aynı kaynak politikasının veya sanal alanın ihlali ile gerçekleşmektedir.
Genel JavaScript'in alt kümeleri (ADsafe, Secure ECMAScript (SES)), özellikle üçüncü taraflarca oluşturulan kodlarda (reklamlar gibi) daha yüksek düzeyde güvenlik sağlar.[71][72] Closure Toolkit, üçüncü taraf JavaScript ve HTML'nin güvenli bir şekilde yerleştirilmesi ve yalıtılması için başka bir projedir.[73]
İçerik Güvenliği Politikası, bir Web sayfasında yalnızca güvenilir kodun yürütülmesini sağlamanın ana yöntemi ve amacıdır.
JavaScript ile ilgili yaygın bir güvenlik sorunu,aynı kaynak ilkesinin ihlali olansiteler arası komut dosyası çalıştırmadır (XSS). XSS güvenlik açıkları, bir saldırgan çevrimiçi bankacılık web sitesi gibi hedeflenen bir Web sitesinin kurbana sunulan web sayfasına kötü amaçlı bir komut dosyası eklemesine neden olduğunda ortaya çıkar. Bu örnekteki komut dosyası daha sonra kurbanın ayrıcalıklarıyla bankacılık uygulamasına erişebilir, potansiyel olarak gizli bilgileri ifşa edebilir veya kurbanın izni olmadan para transfer edebilir. XSS güvenlik açıklarına bir çözüm, güvenilmeyen verileri görüntülerkenHTML çıkışını kullanmaktır.
Bazı tarayıcılar, saldırganın kötü amaçlı komut dosyası içeren bir URL sağladığındayansıyan XSS saldırılarına karşı kısmi koruma içerir. Ancak, bu tarayıcıların kullanıcıları bile, kötü amaçlı kodun bir veritabanında depolandığı saldırılar gibi diğer XSS saldırılarına karşı savunmasızdır. Yalnızca sunucu tarafında Web uygulamalarının doğru tasarımı XSS'yi tamamen önleyebilir.
Tarayıcı yazarlarının uygulama hataları nedeniyle de XSS güvenlik açıkları oluşabilir.[74]
Bir başka siteler arası güvenlik açığı,siteler arası istek sahteciliğidir (CSRF). CSRF'de, bir saldırganın sitesindeki kod, kurbanın tarayıcısını, kullanıcının hedef sitede amaçlamadığı eylemleri gerçekleştirmesi için kandırır (bir bankada para transferi gibi). Hedef siteler, istek doğrulaması için yalnızca tanımlama bilgilerine güvendiğinde, saldırganın sitesindeki koddan kaynaklanan istekler, başlatan kullanıcının aynı geçerli oturum açma bilgilerini taşıyabilir. Genel olarak, CSRF'nin çözümü, kalıcı etkileri olabilecek herhangi bir isteğin kimliğini doğrulamak için yalnızca çerezlerde değil, gizli bir form alanında bir kimlik doğrulama değeri talep etmektir. HTTP Yönlendiren başlığını kontrol etmek de yardımcı olabilir.
"JavaScript ele geçirme", bir saldırganın sitesindeki<script> etiketinin, kurbanın sitesindeJSON veya JavaScript gibi özel bilgiler döndüren bir sayfadan yararlandığı bir CSRF saldırısı türüdür. Olası çözümler şunları içerir:
özel bilgi döndüren herhangi bir yanıt içinPOST veGET parametrelerinde bir kimlik doğrulama belirteci eklemek.
İstemci-sunucu uygulamalarının geliştiricileri, güvenilmeyen istemcilerin saldırganların denetimi altında olabileceğini bilmelidir. Uygulama yazarı, JavaScript kodunun amaçlandığı gibi (veya hiç) çalışacağını varsayamaz çünkü koda gömülü herhangi bir sır, belirli bir düşman tarafından ayıklanabilir. Bazı çıkarımlar şunlardır:
Web sitesi yazarları, ham kaynak kodunun istemciye gönderilmesi gerektiğinden JavaScript'lerinin nasıl çalıştığını tam olarak gizleyemezler. Kodgizlenebilir, ancak şaşırtma tersine mühendislikle yapılabilir.
JavaScript form doğrulaması güvenlik değil, yalnızca kullanıcılar için kolaylık sağlar. Bir site, kullanıcının hizmet şartlarını kabul ettiğini doğrularsa veya yalnızca sayı içermesi gereken alanlardan geçersiz karakterleri filtrelerse, bunu yalnızca istemcide değil sunucuda yapmalıdır.
Komut dosyaları seçici olarak devre dışı bırakılabilir, bu nedenle bir görüntüyü kaydetmek için sağ tıklamak gibi işlemleri önlemek için JavaScript'e güvenilemez.[75]
Bir saldırgan tarafından ayıklanabileceğinden, şifreler gibi hassas bilgileri JavaScript'e gömmek çok kötü bir uygulama olarak kabul edilir.[76]
Npm ve Bower gibi paket yönetim sistemleri, JavaScript geliştiricileri arasında popülerdir. Bu tür sistemler, bir geliştiricinin, programlarının diğer geliştiricilerin program kitaplıklarına olan bağımlılıklarını kolayca yönetmesine izin verir. Geliştiriciler, kitaplıkların koruyucularının onları güvenli ve güncel tutacağına güvenirler, ancak bu her zaman böyle değildir. Bu kör güven nedeniyle bir güvenlik açığı ortaya çıktı. Güvenilir kitaplıklar, kitaplıklara dayanan tüm programlarda hataların veya güvenlik açıklarının ortaya çıkmasına neden olan yeni sürümlere sahip olabilir. Yani bir kitaplık vahşi doğada bilinen güvenlik açıklarıyla yamasız kalabilir. 133 bin web sitesi örneği incelenmiş bir çalışmada, araştırmacılar web sitelerinin %37'sinin bilinen en az bir güvenlik açığına sahip bir kitaplık içerdiğini buldu.[77] "Her web sitesinde kullanılan en eski kütüphane sürümü ile bu kütüphanenin mevcut en yeni sürümü arasındaki ortalama gecikme, ALEXA'da 1.177 gündür ve halen aktif olarak kullanılan bazı kütüphanelerin geliştirilmesi yıllar önce durduruldu."[77] Başka bir olasılık, bir kütüphanenin yöneticisinin kütüphaneyi tamamen kaldırabilmesidir. Bu, Mart 2016'da Azer Koçulu'nun deposunu npm'den kaldırmasıyla meydana geldi. Bu, kütüphanelerine bağlı on binlerce programın ve web sitesinin bozulmasına neden oldu.[78]
JavaScript, bazılarıarabellek taşmaları gibi kusurlara sahip olabilen çok çeşitli tarayıcı yetenekleri için bir arabirim sağlar. Bu kusurlar, saldırganların kullanıcının sisteminde istedikleri herhangi bir kodu çalıştıracak komut dosyaları yazmasına izin verebilir. Bu kod hiçbir şekilde başka bir JavaScript uygulamasıyla sınırlı değildir. Örneğin, arabellek taşması istismarı, bir saldırganın süper kullanıcı ayrıcalıklarıyla işletim sistemininAPI'sine erişmesine izin verebilir.
Bu kusurlar Firefox, Internet Explorer,[79] ve Safari gibi büyük tarayıcıları etkilemiştir.
Video oynatıcılar,Adobe Flash ve Microsoft Internet Explorer'da varsayılan olarak etkinleştirilen çok çeşitliActiveX denetimleri gibi eklentiler, JavaScript aracılığıyla yararlanılabilen kusurlara da sahip olabilir (bu tür kusurlardan geçmişte yararlanılmıştır).
Windows Vista'da Microsoft, Internet Explorer işlemini sınırlı ayrıcalıklarla çalıştırarak arabellek taşmaları gibi hata risklerini kontrol altına almaya çalışmıştır.[80]Google Chrome benzer şekilde sayfa oluşturucularını kendi "sandbox "larıyla sınırlar.
Web tarayıcıları, örneğin dosya oluşturmak veya silmek için gerekli ayrıcalıklarla birlikte JavaScript'i sanal alanın dışında çalıştırabilir. Bu tür ayrıcalıkların Web'den koda verilmesi amaçlanmamıştır.
Web'den JavaScript'e yanlış ayrıcalıklar verilmesi, hem Internet Explorer hem de Firefox'taki güvenlik açıklarında rol oynamıştır. Windows XP Service Pack 2'de Microsoft, Internet Explorer'da JScript'in ayrıcalıklarını düşürmüştür.[81]
Microsoft Windows, bir bilgisayarın sabit sürücüsündeki JavaScript kaynak dosyalarının genel amaçlı, korumalı alanda olmayan programlar olarak başlatılmasına izin verir (bkz:Windows Komut Dosyası Ana Bilgisayarı ). Bu, JavaScript'i (VBScript gibi) birTruva atı için teorik olarak uygun bir vektör yapar, ancak JavaScript Truva atları pratikte nadirdir.[82]
2015 yılında, güvenlik araştırmacıları tarafından bir makalede, birRowhammer saldırısının JavaScript tabanlı bir kavram kanıtı uygulaması açıklanmıştır.[83][84][85]
2017 yılında, tarayıcı üzerinden JavaScript tabanlı bir saldırınınASLR'yi atlayabileceği gösterildi. Buna "ASLR⊕Cache" veya AnC denir.
2018'de Intel ve diğer işlemcilerde Spekülatif Yürütmeye karşıSpectre saldırılarını açıklayan makale bir JavaScript uygulamasını içeriyordu.
Bazı tarayıcılarda yerleşikprofil oluşturucular bulunur. Benchmark.js ve jsbench gibi bağımsız profil oluşturma kitaplıkları da oluşturulmuştur.[86][87]
Birçokmetin düzenleyici (IDE), JavaScript kodu için sözdizimi vurgulama desteğine sahiptir.
Brendan Eich, özellikle JavaScript programlama dilinin yaratıcısı olarak tanınan Amerikalı bir yazılım geliştiricisidir. Eich, 1995 yılında Netscape Communications Corporation'da çalışırken JavaScript'i geliştirmiştir.
Yaygın bir yanılgı, JavaScript'inJava ile aynı olduğuna yöneliktir. Her ikisinin de gerçekten de C-benzeri bir sözdizimi vardır (C dili onların en yakın ortak ata dilidir). Ayrıca, genelliklekorumalı alana alınırlar (bir tarayıcı içinde kullanıldığında) ve JavaScript, Java'nın sözdizimi ve standart kitaplığı göz önünde bulundurularak tasarlanmıştır. Özellikle, tüm Java anahtar sözcükleri orijinal JavaScript'te ayrılmıştır, JavaScript'in standart kitaplığı Java'nın adlandırma kurallarını takip eder ve JavaScript'inMath veDate objeleri Java 1.0'dan alınan sınıflara dayanır.[88]
Java ve JavaScript ilk olarak 1995'te ortaya çıktı, ancak Java Sun Microsystems'denJames Gosling ve JavaScript ise Netscape Communications'danBrendan Eich tarafından geliştirildi.
İki dil arasındaki farklılıklar benzerliklerinden daha belirgindir. Java'nınstatik yazımı vardır, JavaScript'in yazımı isedinamiktir. Java, derlenmiş bayt kodundan yüklenirken JavaScript, insan tarafından okunabilir kaynak kodu olarak yüklenir. Java'nın objelerisınıf tabanlıdır, JavaScript'ler iseprototip tabanlıdır. Son olarak, Java, Java 8'e kadar işlevsel programlamayı desteklemezken, JavaScript,Scheme'den etkilenerek bunu başından beri yapmıştır.
JSON veya JavaScript Object Notation, JavaScript'in obje değişmez sözdiziminin bir alt kümesi olarak tanımlanan genel amaçlı bir veri değişim biçimidir.
TypeScript (TS),Microsoft tarafından geliştirilmekte ve desteklenmektedir.[89] TS, JavaScript'in katı şekilde (strictly-typed) yazılan versiyonudur. TS, değişkenlere ve fonksiyonlara, tür açıklamaları ekleyerek farklılıkları gösterir ve JS içinde türlerin tanımlanması için bir tanıtım dilidir. Bunun dışında TS, JS ile istemci tarafında çalıştırılması, kolay, anlaşılır bir şekilde aktarılmasına izin vermek ve diğer JS kodlarıyla birlikte çalışabilmesi için hemen hemen aynı özellik setini paylaşır.[90]
2017'den beri web tarayıcıları, birJavaScript motorununweb sayfası komut dosyalarının performans açısından kritik bölümlerini yerel hıza yakın yürütmesini sağlayan ikili bir biçim olanWebAssembly'yi desteklemektedir.[91] WebAssembly kodu, normal JavaScript koduyla aynısanal alanda çalışır.
asm.js, WebAssembly'nin öncüsü olarak hizmet veren bir JavaScript alt kümesidir.[92]
JavaScript, Web'in baskın istemci tarafı dilidir ve birçok web sitesi komut dosyası ağırlıklıdır. Bu nedenle, geliştirme sürecine yardımcı olabilecek diğer dillerde yazılmış kodu dönüştürmek içinaktarıcılar oluşturulmuştur.[36]
^"Introducing JScript .NET".Microsoft Developer Network. Microsoft. 14 Temmuz 2000. 10 Kasım 2017 tarihindekaynağından arşivlendi. Erişim tarihi:10 Nisan 2018.[S]ince the 1996 introduction of JScript version 1.0 ... we've been seeing a steady increase in the usage of JScript on the server—particularly in Active Server Pages (ASP)