JavaScript

Wikipediasta
Siirry navigaatioon Siirry hakuun
JavaScript
Paradigma monia: olio-ohjelmointi (prototyyppipohjainen), imperatiivinen, funktionaalinen
Tyypitys heikko, dynaaminen
Yleinen suoritusmalli tulkattava
Muistinhallinta automaattinen
Julkaistu 4. joulukuuta 1995[1]
Suunnitellut Brendan Eich
Kehittäjä alun perin Netscape, nykyään Ecma International
Vakaa versio ECMAScript 2024[2]
Merkittävimmät toteutukset V8, SpiderMonkey, JavaScriptCore, Chakra
Vaikutteet C, Java, Perl, Python, Scheme, Self
Vaikuttanut TypeScript, Dart, Haxe, CoffeeScript, QML, Objective-J, LiveScript, JScript .NET, ActionScript
Käyttöjärjestelmä alustariippumaton
Uutisryhmä comp.lang.javascript

JavaScript on alun perin Netscapen kehittämä, pääasiassa verkkoympäristössä käytettävä ohjelmointikieli.

JavaScript on dynaamisesti ja heikosti tyypitetty, tulkattava, oliopohjainen komentosarjakieli, jonka syntaksi perustuu löyhästi C-ohjelmointikieleen. Kielen semantiikka ja suunnittelu on saanut vaikutteita Self- ja Scheme-ohjelmointikielistä. Java on ollut merkittävä osa JavaScriptin kehitystä. JavaScript on saanut vaikutteita muun muassa sen syntaksista ja standardikirjastosta. Math- ja Date-oliot perustuvat Java 1.0:n luokkiin ja niitä voidaan hyödyntää myös JavaScriptissä. Kaikesta huolimatta JavaScript ja Java eroavat toisistaan niin paljon, että niitä ei pitäisi sekoittaa toistensa kesken, vaan kuuluisi kohdella täysin eri kokonaisuuksina.

Web-kehitykseen käytetään usein JavaScriptiin perustuvia ohjelmistokehyksiä (esim. Svelte, AngularJS ja Next.js), käyttöliittymäkirjastoja (kuten React) sekä JavaScriptin laajennoksia ja JavaScriptiksi käännettäviä (engl. transpiler) kieliä kuten JSX ja TypeScript – ei niinkään natiivia JavaScriptiä suoraan. JavaScriptiä ei tule sekoittaa Java-kieleen; nimi on peräisin Netscapen ja Javan kehittäneen Sunin lisenssisopimuksesta ja pyrkimyksestä markkinoida JavaScriptistä Javan "apukieli"[3]. Kielen standardin virallinen nimi on ECMAScript.

JavaScript-tiedoston ikoni.

JavaScriptin kehitti alun perin Netscapen Brendan Eich nimellä Mocha. Nimi muutettiin LiveScriptiksi ja viimein markkinointisyistä JavaScriptiksi Netscapen liittouduttua Java-kielen kehittäneen Sun Microsystemsin kanssa. JavaScript on kuitenkin Java-ohjelmointikielestä eroava tekniikka.[4] JavaScript tuli käyttöön Netscape Navigator 2.0 -selaimessa maaliskuussa 1996.

JavaScriptin suosion ansiosta Microsoft kehitti siitä yhteensopivan version, jolle se antoi tavaramerkkisyistä nimen JScript.[4] Tämä toiminnallisuus lisättiin Internet Explorerin versioon 3.0, joka julkaistiin elokuussa 1996. Microsoft aloitti JScriptin standardoinnin Ecma International -järjestössä. Ensimmäinen versio standardista julkaistiin kesäkuussa 1997[5].

2000-luvun alussa Internet Explorerin hallitessa selainten välistä kilpailua, asiakaspuolen skriptaus oli pysähtynyt. Tähän alkoi kuitenkin näkymään muutosta vuodesta 2004 eteenpäin, kun Netscapen seuraaja Mozilla julkaisi Firefox-selaimen. Firefox sai paljon hyvää vastaanottoa ja vei merkittävän markkinaosuuden Internet Explorerilta.lähde?

Google esitteli Chrome-selaimensa vuonna 2008, jossa oli V8 JavaScript -moottori, joka oli nopeampi kuin kilpailijansa. Tärkein innovaatio oli just-in-time -kääntäminen (JIT), joten muut selainten valmistajat joutuivat uudistamaan moottoreitaan kilpaillakseen JIT:in kanssa.lähde?

Heinäkuussa 2008 eri osapuolet kokoontuivat konferenssiin Oslossa. Tämä johti lopulta sopimukseen yhdistää kaikki asiaankuuluvat työt ja ajaa kieltä eteenpäin. Tuloksena oli ECMAScript 5 -standardi, joka julkaistiin joulukuussa 2009. Kunnianhimoinen työ ohjelmistokielen parissa jatkui muutamia vuosia, joka kulminoitui laajaan kokoelmaan erilaisia lisäyksiä ja hienosäätöjä. Tämä formalisoitiin ECMAScript 6:n julkaisulla vuonna 2015.lähde?

Käyttöaiheet

[muokkaa | muokkaa wikitekstiä]

JavaScriptin tärkein sovellus on mahdollisuus lisätä verkkosivuille dynaamista toiminnallisuutta. Sitä käytetään tavallisimmin osana verkkoselaimia, joiden toteutukset sallivat asiakaspuolen skriptien interaktion käyttäjän kanssa, selaimen rajoitetun hallinnan, asynkronisen kommunikaation ja käyttäjälle näytettävän dokumenttisisällön muokkaamisen. JavaScriptin käyttö on yleistynyt sen yksinkertaisuuden, joustavuuden, monipuolisten lisäosien ja tehokkuuden vuoksi myös palvelinpuolella[6], jolloin sitä voidaan käyttää esimerkiksi Node.js -ajoympäristössä. Lisäksi ohjelmointikieltä käytetään pelien kehityksessä sekä työpöytä- ja mobiilisovellusten luomisessa.

JavaScript on heikosti tyypitetty, mikä tarkoittaa, ettei käytössä olevia tietorakenteita erikseen määritellä ja JavaScript pyrkii yleensä muuttamaan tyyppejä automaattisesti virheen nostamisen sijaan. Esimerkiksi taulukko voi kehittyä oliomaiseksi muuttujarakenteeksi ja kokonaisluvun ja liukuluvun eroja ei tarvitse välttämättä miettiä.

JavaScriptin primitiiveihin kuuluvat Boolean, null, undefined, Number, String, BigInt, Symbol ja Object. Tyypitys on dynaaminen ja ajonaikaiset tyyppimuunnokset ovat tavallisia. Literaaleihin kuuluvat tekstiliteraalit "string", taulukkoliteraalit [1, 2, 3, /* tyhjä */, 5, ], Boolen literaalit true ja false, numeeriset literaalit kuten 10, 3.14 ja 1.5e-9, objektiliteraalit kuten { nimi: "Arvo", "taulukko": [1, 2, 3], teeJotain() { ... }, }, regex-literaalit /[A-Z]+/ ja mallineet `Hei, ${nimi}!'\n'`.[7]

Funktio määritellään deklaraatiosyntaksilla function teeJotain(x) { ... } tai lausekkeena var teeJotain = function (x) { ... };. Lausekesyntaksi on tavallinen, kun funktiota on tarkoitus käyttää toisen funktion parametrina. Nimettömiin lambdafunktioihin käytetään fat arrow-syntaksia (x) => x.length tai yksinkertaisesti function () { ... }. Välittömästi kutsuttu nimetön funktio voi olla myös (function () { ... })();. Funktion sisänäkymässä on käytössä erityinen arguments-taulukko, joka sisältää järjestyksessä kaikki funktiolle annetut parametrit. Vastaavasti ylimääräisten parametrien kaappaamiseen voidaan käyttää ...nimi-syntaksia tyylillä function nimi(x, ...y) { ... }. Jos taas määritettyjä argumentteja ei anneta, niiden arvo on undefined tai oletusarvo function nimi(x = "oletus") { ... }. Funktioiden käyttö on sallittua ennen niiden määritelmiä (engl. function hoisting), jos funktio on määritelty deklaraatiotyylillä.[7]

Muuttuja määritellään var (funktionäkymä, muuttuva), let (blokkinäkymä, muuttuva) ja const (blokkinäkymä, muuttumaton) avainsanoilla. JavaScript ei kuitenkaan edellytä näitä vaan luo avainsanan puuttuessa alustamattoman globaalin muuttujan. Tällainen joustavuus on kielelle tyypillistä. var-sanalla määriteltyjen muuttujien käyttö on myös sallittua ennen määrittelyä, mutta niiden arvo on tällöin undefined (engl. variable hoisting). Destrukturointi on mahdollista tyylillä let [eka, toka, kolmas] = teeJotain(input);.[7]

Lauseet erotellaan puolipisteillä (mutta tämä ei ole pakollista yksirivisissä lauseissa). Lauseisiin kuuluvat myös[7]

  • blokkilauseet { ... }
  • if-else-lause if (...) { ... } else if (...) { ... } else { ... } (undefined, null, 0, NaN ja "" tulkitaan olevan false; kaikki muut arvot tulkitaan olevan true)
  • switch-lause switch (x) { case y: ...; case z: ...; default: ...; }
  • poikkeustenhallinnan throw ja try { ... } catch (e) { ... } finally { ... }
  • for-silmukka for (let x = 0; x < 10; x++) { ... }
  • for-in-silmukka for (x in y) { ... }, missä y on ominaisuuksia sisältävä objekti ja x ominaisuuden nimi
  • for-of-silmukka for (x of y) { ... }, missä y on iteroitava objekti ja x on arvo
  • do-while-silmukka do { ... } while (...);
  • while-silmukka while (...) { ... }

Operaattoreita ovat[7]

  • sijoitusoperaattori = ja tämän päivittävät versiot kuten += ja ehdolliset versiot kuten &&= (true) ja ??= (null)
  • vertailuoperaattorit kuten heikkoyhtäläisyys == ja vahva (sama tyyppi) yhtäläisyys ===
  • aritmeettiset operaattorit kuten jakojäännös x % y ja inkrementointi ++x
  • bittioperaattorit kuten ja & ja ei ~
  • loogiset operaattorit kuten ja &&, tai ||, ei ! ja ?? (null tai undefined)
  • ehto-operaattori x ? y : z
  • delete, typeof, void, in, instanceof, new
  • ryhmittely ( ... )

Modularisointi

[muokkaa | muokkaa wikitekstiä]

JavaScript-moduulissa käytetään export-lausetta kuten export { muuttuja, nimi, funktio, Luokka }; ja nämä jaetut objektit tuodaan uuteen globaaliin näkymään tyylillä import { muuttuja, funktio } from "./polku/moduuli.js". HTML-tiedostossa tulee tällöin käyttää type-attribuuttia <script type="module" src="..."></script>. Nimetyn viennin sijaan voidaan myös käyttää export default nimi;. Jos taas halutaan vaihtaa tuotujen objektien nimiä, voidaan käyttää as-avainsanaa tyylillä import { funktio as f, nimi as n } from "./polku/moduuli.js";. Useat tuodut objektit voidaan myös laittaa moduuliobjektiin tyylillä import * as Moduuli from "./polku/moduuli.js";. Vienti voidaan myös merkitä avainsanalla await, jolloin moduulin tuonti ei estä muita prosesseja, jotka eivät riipu tästä await-moduulista. Moduulit on parasta kehittää niin, että ne toimivat eri ajoympäristöissä (web-selain, Node.js). Globaalit muuttujat ovat yhden globaalin objektin ominaisuuksia, kuten web-selaimessa window.muuttuja. Funktiot ja blokkilauseet (engl. block statement) luovat paikallisia näkymiä ja globaalit nimet näkyvät kaikkialle.[7]

Olio-ohjelmointi

[muokkaa | muokkaa wikitekstiä]

JavaScriptin oliomallin perusyksikköjä ovat object- ja function-oliot. Oliomalli ja sen enkapsulaatio ja periytyvyys pohjautuvat prototyyppeihin, ei luokkiin kuten useimmissa olio-ohjelmointikielissä (esim. Smalltalk, C++, Java, Ruby).[8]

Koska JavaScript on prototyyppipohjainen kieli, olioiden luominen ei edellytä luokkia. Oliot voidaan rakentaa suoraan "tyhjästä" tai jonkin toisen olion prototyypin pohjalta. Prototyypit tukevat siis eräänlaista versiota perinnästä, joka on tärkeä käsite luokkapohjaisissa kielissä, kuten Javassa. Jokaisella JavaScript-oliolla on sisäänrakennettuna ominaisuutena jokin prototyyppi[9]. Prototyypit ovat myös olioita ja näin myös prototyypeillä on omat prototyyppinsä. Tästä muodostuu ns. prototyyppiketju, joka jatkuu niin pitkään kunnes päästään olioon, jonka prototyyppi on null. Tämä muistuttaa hieman perintäketjua luokkapohjaisissa kielissä. Kun olion attribuuttia referoidaan esim. olio.ominaisuus, sen arvo haetaan prototyyppiketjusta tai arvon puuttuessa palautetaan undefined.

Objektit voivat periä ominaisuudet. prototyypiltä __proto__-syntaksilla const o = { __proto__: prototyyppi, muuttuja: 10, }; tai funktiokonstruktorin avulla function Konstruktori(x) { ... } ja Konstruktori.prototype.metodi = function() { ... };. this-avainsana mahdollistaa objektiin viittaamisen tämän metodin sisällä ja super-syntaksi mahdollistaa vastaavasti objektin prototyyppiin/vanhempaan viittaamisen. Konstruktoria kutsutaan käyttämällä new-avainsanaa funktiokutsun edellä esim. const auto = new Auto("Toyota", 2007);. Vaihtoehtoisesti voidaan käyttää Object.create-metodia ja prototyyppiobjektia.[7]

Prototyyppijärjestelmän päälle JavaScriptiin on myös kehitetty perinteisempi luokkajärjestelmä. Uusi luokka määritellään syntaksilla class Nimi { constructor() { ... } nimi2 = 1; static nimi2 = 2; metodi() { ... } #nimi3 = 3; }. static merkitsee luokkaominaisuuden ja # yksityisen ominaisuuden. Luokasta tehdään instanssi new-avainsanalla const i = new Nimi();. Luokat sallivat myös aksessorikentät lisäämällä erityiset metodit get ominaisuus() { return ...; } ja set ominaisuus(x) { ... }. Periminen onnistuu class Luokka extends Yläluokka { ... }.