ECMAScript | |
---|---|
Kieliluokka | Ohjelmointikielten , toiminnallisen ohjelmointikielen ja moniparadigmaohjelmointikielen eritelmät |
Esiintyi | kesäkuuta 1997 |
Tekijä | Brendan Eich ja Ecma International |
Kehittäjä | Brendan Eich |
Tiedostotunniste _ | .es[2] |
Vapauta | ECMAScript 2022 [Spec 1] (kesäkuu 2022 ) |
Tyyppijärjestelmä | Ankka |
Murteet | JavaScript , JScript , ActionScript , JScript.NET , QtScript |
Vaikutettu | Self [1] , C , Scheme [1] , Perl [1] , Python , Java [1] , AWK [1] |
vaikutti | Tavoite-J |
Verkkosivusto | ecma-international.org _ |
ECMAScript on upotettava, laajennettava, I/O -vapaa ohjelmointikieli , jota käytetään muiden komentosarjakielten rakentamisen perustana [3] .
ECMAScript on kansainvälisen järjestön ECMA : n standardoima ECMA-262- spesifikaatiossa . Kielilaajennukset: JavaScript , JScript ja ActionScript .
Kieli on peräisin useista teknologioista, joista tunnetuimmat ovat JavaScript- ja JScript -kielet . Eritelmän ensimmäisen version kehittäminen aloitettiin marraskuussa 1996. Eritelmä hyväksyttiin kesäkuussa 1997. Toimitettu ISO/IEC JTC 1:lle Fast-Tracking -hyväksyntää varten, se toimi kansainvälisen ISO/IEC 16262 -standardin perustana . Kesäkuussa 1998 ECMA:n yhtiökokous hyväksyi ECMA-262:n toisen painoksen, joka vastaa standardia ISO / IEC 16262. Spesifikaation kolmas painos erosi edellisestä ottamalla käyttöön säännöllisten lausekkeiden tuen, parantamalla merkkijonotukea ja ottamalla käyttöön uusia ohjausrakenteita. , poikkeusmekanismi, muotoilu numeerista syöttöä käytettäessä ja joitain muita muutoksia[Spesifikaatio 2] .
ECMAScript tukee viittä primitiivistä tietotyyppiä :
ECMAScriptin numeerinen tietotyyppi vastaa IEEE 754-2008 -standardin määrittelemää 64-bittistä liukulukumuotoa , paitsi että standardissa [4] määritellyt erilaiset Not-a-Number- arvot esitetään tällä kielellä. yksittäisellä erikoisarvolla NaN [ Specification 4] .
David Flanagan kutsuu nolla- ja määrittelemättömiä tietotyyppejä epävirallisesti "triviaaleiksi" tyypeiksi , koska jokainen niistä määrittelee vain yhden arvon [5] .
Kielellä on myös "yhdistetty" tietotyyppi [5] :
Luettelon kuuden tietotyypin lisäksi ECMAScript tukee seitsemää muuta, joita käytetään yksinomaan arvioitujen lausekkeiden välitulosten tallentamiseen:
JavaScript-kielen suosio ja erityyppisten tietojen käsittelyn epätriviaalisuus johtivat akateemisen tutkimuksen käyttöön ECMAScript-tietotyyppien jäsentämisen alalla, jonka tavoitteena on luoda täysimittainen koodianalysaattori, jota voitaisiin käyttää integroidussa kehityksessä . ympäristöt [6] .
ECMAScriptissä on viisitoista erilaista ohjetta, jotka on lueteltu alla olevassa taulukossa:
Nimi | alkuperäinen nimi | Lyhyt tiedot | lopullinen ; [Spesifikaation 8] |
---|---|---|---|
Lohko | Englanti lohko | {[<ohjeet>]} | − |
Muuttuva ilmoitus | Englanti VariableStatement | var <muuttujamäärittelyjen luettelo> | + |
Tyhjä ohje | Englanti EmptyStatement | ; | + |
Ilmaisu | Englanti ExpressionStatement | [merkkijono ∉ {{, funktio}] -lause | + |
Kunto | Englanti IfSatement | if (<инструкция>) <выражение>[ else <выражение>] | − |
Kierrä | Englanti IterationStatement | tee <lauseke> kun (<lause>) while (<lauseke>) <lauseke> |
+/− [~1] |
Jatkoa | Englanti ContinueStatement | jatka [<tunniste>] | + |
Keskeyttää | Englanti BreakStatement | tauko [<tunniste>] | + |
Palata | Englanti Palautuslauseke | palauttaa [<ohje>] | + |
Yhdistelmä | Englanti Lausunnon kanssa | kanssa (<lause>) <lauseke> | − |
Label | Englanti LabelledStatement | <tunniste>: <lauseke> | − |
Valinta | Englanti SwitchStatement | Vaihda (<lauseke>) kirjainkoko <lauseke>: [<lausekkeet>][ tapaus <lauseke>: [<lausekkeet>] ...] [oletus: [<lausekkeet>]] | − |
Poikkeuksen heittäminen | Englanti ThrowStatement | heittää <ohje> | + |
yritä estää | Englanti TryStatement | yritä <block> catch (<tunniste>) <block> yritä <block> lopuksi <block> yritä <block> catch (<tunniste>) <block> lopuksi <block> |
− |
(uusi [Spec 9] ) Debugger | Englanti Virheen korjaaja | virheen korjaaja | − |
Huolimatta pakollisesta puolipisteestä neljännessä sarakkeessa mainituissa tapauksissa, spesifikaatio ilmoittaa mekanismin merkkijonojen automaattiseen täydennykseen puolipisteillä , mikä johtaa siihen, että jos rivinvaihto tapahtuu, rivinvaihtoa edeltävä ohje voidaan varustaa tällä merkillä [ Specification 8] , joka on kritiikin kohteena [7] .
Ohjeita, jotka muuttavat merkitystä käytettäessä rivinvaihtoa sisällä [Specification 8]Esimerkki ohjeen merkityksen muuttamisesta
return { tila : "valmis" };Tässä korostettu rivi sisältää kielen mukaisen ohjeen, ja koska uusi rivi seuraa, mekanismi rivien automaattiseen täydentämiseen puolipisteillä laukeaa. Sen sijaan, että yllä olevan koodin sisältävä funktio palauttaisi kohteen, jonka arvo on ominaisuus status, se palauttaa undefined.
Vaikka objektin kirjaimellinen muoto ei ole koodilohko, yhtenäiset sulut voivat johtaa virheisiin. Sopivan koodausstandardin kehittäminen tai käyttöönotto voi vähentää niiden esiintymisen todennäköisyyttä . Sisennystyylin valinnalla on merkitystä . Erityisesti Allman- ja Whitesmith-tyylit sekä JavaScript-koodin Horstman- tyyli ja GNU-tyyli ovat vanhentuneita useimpien ohjeiden mukaan [8] toisin kuin K&R- , 1TBS- , BSD KNF -tyylejä .
Automaattinen täydennys epäonnistuiJos seuraavalle riville kirjoitettu lauseke voi syntaktisesti olla jatkoa edellisen rivin lausekkeelle, mekanismi rivien automaattiseen täydennykseen puolipisteillä ei toimi [9] .
func () [ 'h1' , 'h2' ]. forEach ( funktio ( t ) { handleTag ( t ) })Tässä esimerkissä toisen rivin hakasulkeet tulkitaan viittaavat func(:n) palauttamaan taulukkoelementtiin. Suluissa olevaa pilkkua käsitellään vastaavana operaattorina, joka palauttaa 'h2'. Joten koodi muunnetaan seuraavaksi:
func ()[ 'h2' ]. forEach ( function ( t ) { handleTag ( t ); });Koodausstandardeissa on tapana vaatia puolipisteitä, vaikka kielen syntaksi sallii niiden jättämisen pois [Coding Standards 1] [Coding Standards 2] [Coding Standards 3] [Coding Standards 4] [Coding Standards 5] .
Lohkot ja laajuusToinen ECMAScriptin ominaisuus suhteessa muihin C-kaltaisiin kieliin on, että tällä kielellä lohkot eivät muodosta aluetta . Lohkossa ilmoitetut muuttujat koskevat koko funktiota, joka sisältää lohkon [10] [11] .
Tässä koodiosassa muuttuja ilmoitetaan uudelleen korostetuilla riveillä:
funktio foo ( ) { varsum = 0 ; for ( var i = 0 ; i < 42 ; i + = 2 ) { var tmp = i + 2 ; summa += i * tmp ; } for ( var i = 1 ; i < 42 ; i += 2 ) { summa += i * minä ; } hälytys ( tmp ); palautussumma ; _ } foo ();Lisäksi ensimmäisen silmukan sisällä (rivi 4) ilmoitettu muuttuja tmp on laillinen pääsy silmukan ulkopuolelta (rivi 10) kielen syntaksin mukaan.
Laajuuden ja lohkojen luonteesta johtuen on suositeltavaa ilmoittaa muuttujat funktioiden alussa lähdekoodin laadun ylläpitämiseksi [10] [Koodausstandardit 1] [Koodausstandardit 4] .
Muuttujien ilmoituksetMuuttujat määritellään avainsanoilla var, let, const. Kun muuttuja ilmoitetaan, se sijoitetaan varfunktiota vastaavaan laajuuteen let, constja koodilohkon tapauksessa. Jos muuttuja ilmoitetaan funktioiden ulkopuolella, se sijoitetaan globaaliin laajuuteen. Muuttujan luominen tapahtuu, kun vastaanotetaan funktion ohjaus ja sen ilmoitus. Tai ohjelma, jos muuttuja on globaali. Kun muuttuja luodaan ECMAScriptissä, se saa arvon undefined. Jos muuttuja ilmoitetaan alustuksella , alustus ei tapahdu muuttujan luomishetkellä, vaan kun käskyn sisältävä rivi var[Specification 10] suoritetaan .
Kun poistat valitun rivin kommentteja, näytössä ei näy numeroa , vaan määrittelemätöntä :
var a = 42 ; function foo () { hälytys ( a tyyppi ); // var a = 10; } foo ();Kun muuttuja luodaan, se saa sisäisen ominaisuuden {DontDelete}, eikä sitä voida poistaa delete[Specification 10] -operaattorilla . evalPoikkeuksen muodostavat kontekstissa [12] [Specification 11] ilmoitetut muuttujat .
Monet lähteet [13] [14] [15] [16] [17] [18] ilmoittavat mahdollisuuden ilmoittaa implisiittisesti muuttujat ECMAScriptissä, kun määritetään kelvollinen tunniste, joka ei ole muodollinen funktion argumentti, ilman että sitä on ensin ilmoitettava var. Kuitenkin kielimäärittelyn terminologiassa tässä tapauksessa luodaan globaalin objektin ominaisuus, ei muuttuja [12] [Specification 10] .
Korjaamalla koodausstandardiin muuttujien ilmoittamistarpeen ennen niiden käyttöä [Coding Standards 1] [Coding Standards 4] (tai korjaamalla tarve käyttää nimiavaruuksia kaikille globaaleille objekteille [Coding Standards 2] ) vältetään hienovaraiset virheet ja estetään identtisesti nimettyjen muuttujien vuorovaikutus koodin eri osissa [19] .
Seuraavat sanat ovat kielen avainsanoja, eikä niitä voida käyttää tunnisteina [Spec 12] :
break do instanceof typeof tapaus muuten uusi var saalis vihdoin paluu tyhjä jatka vaihtoa varten debugger-toiminto tämän kanssa oletuksena jos heittää poista kokeilemallaVerrattuna spesifikaation kolmanteen painokseen [Specification 13] , viides painos lisäsi avainsanan debuggervastaavan ohjeen kanssa.
Seuraavia sanoja käytetään avainsanoina ehdotetuissa laajennuksissa, ja ne on siksi varattu näiden laajennusten mukauttamismahdollisuuksille [Spesifikaatio 14] :
luokkaluettelo laajenee super jatkuva vientituontiKäytettäessä tiukkaa tilaa seuraavien sanojen katsotaan olevan varattu myöhempää käyttöä varten [Spec 14] :
työvälineet antavat yksityisen julkisen tuoton liitäntäpaketti suojattu staattiseltaSiten tulevaan käyttöön varattujen sanojen määrä on vähentynyt merkittävästi verrattuna kielimäärittelyn kolmanteen painokseen. Aikaisemmin niitä oli 31 [spesifikaatio 15] , ja suuren määrän avainsanoja ja varattuja sanoja, joista suurinta osaa ei käytetä kielessä, arvosteltiin [20] .
ECMAScriptillä on sekä operaattoreita, jotka käyttävät avainsanoja niminä, että operaattoreita, jotka käyttävät välimerkkejä niminä .
Operaattoreiden luokitusECMAScript-operaattorit voidaan jakaa seuraaviin ryhmiin alenevassa tärkeysjärjestyksessä :
Operaattorit ++, --, -, +, ~, !, delete, typeof, void, ?:, =, *=, /=, +=, -=, <<=, >=, >>>=, &=, ovat oikea-assosiatiivisia ( ^=eli |=ne a op b op cvastaavat a op (b op c)). Loput ECMAScript-operaattorit jätetään assosiatiiviseksi [22] .
Ariteetin mukaan ECMAScript -operaattorit on jaettu seuraaviin ryhmiin:
Operaation etumerkin sijainnin mukaan operandeihin nähden ECMAScript-operaattorit jaetaan seuraaviin ryhmiin:
Operaattorit luokitellaan myös operandityypin [25] ja suoritetun toiminnan luonteen mukaan.
ECMAScript-lauseiden ominaisuudetECMAScriptissä ei ole operaattoria, jonka avulla voit tarkistaa, kuuluuko ominaisuus suoraan objektiin vai onko se peritty. Tämä tarkistus suoritetaan käyttämällä hasOwnProperty(). Koska tämä menetelmä ei ole operaattori, se voidaan korvata millä tahansa muulla ominaisuudella [26] .
Operaattori +on kielen ainoa aritmeettinen operaattori, joka on ylikuormitettu merkkijonoargumenteille. Jos ainakin yksi operandeista on merkkijono, +se toimii ketjuttimena , muussa tapauksessa se suorittaa yhteenlaskua [27] [Specification 17] .
Toisin kuin kielissä, joissa void on tietotyyppi, ECMAScriptissä se on operaattori, joka palauttaa arvon undefined[28] .
Operaattori ==tarkistaa tasa-arvon algoritmin mukaan, joka koostuu 10 vaiheesta, mikä joissakin tapauksissa sisältää tyyppimuunnoksen [Specification 18] , joka voi lopulta johtaa ei-ilmeisiin tuloksiin [29] .
Esimerkki työn tuloksista ==(kaikissa luetelluissa tapauksissa operaattorin arvo ===samoilla argumenteilla on false):
hälytys ( "NaN" == NaN ); // väärä hälytys ( NaN == NaN ); // väärä hälytys ( tosi == 1 ); // tosi hälytys ( tosi == 42 ); // väärä hälytys ( null == 0 ); // väärä hälytys ( 0 == "" ); // todellinen hälytys ( "" == 0 ); // tosi hälytys ( "false" == false ); // väärä hälytys ( false == 0 ); // tosi hälytys ( undefined == false ); // väärä hälytys ( null == false ); // väärä hälytys ( undefined == null ); // todellinen hälytys ( " \t\r\n " == 0 ); // tottaECMAScriptin funktiot ovat objekteja [30] [31] . Rakentaja, jolla ne luodaan, on Function(). Funktiot, kuten kaikki muutkin objektit, voidaan tallentaa muuttujiin, objekteihin ja taulukoihin, ne voidaan välittää argumenteina muille funktioille ja funktiot voivat palauttaa ne. Funktioilla, kuten kaikilla muillakin objekteilla, voi olla ominaisuuksia. Olennainen funktioiden erityispiirre on, että niitä voidaan kutsua [30] .
Funktioiden määrittelyECMAScriptissä on kahdenlaisia toimintoja:
Sisäiset toiminnot ovat sisäänrakennettuja objekteja (katso alla ), joita ei välttämättä ole toteutettu ECMAScriptissa [Specification 19] .
Ohjelman tekstissä nimetty toiminto ECMAScriptissa voidaan määrittää jollakin seuraavista tavoista:
// funktion määritys funktion summa ( arg1 , arg2 ) { return arg1 + arg2 ; } // funktion määrittäminen käskyllä var sum2 = function ( arg1 , arg2 ) { return arg1 + arg2 ; }; // funktion määrittäminen objektimerkinnällä var sum3 = new Function ( "arg1" , "arg2" , "return arg1 + arg2;" );Jälkimmäinen menetelmä on vähiten suositeltava, koska se perustuu käytännössä funktion määrittämiseen lausekkeen avulla, mutta samalla se tuottaa koodin kaksinkertaisen tulkinnan (lisätulkinta tapahtuu, kun koodi välitetään rakentajalle), mikä voi vaikuttaa negatiivisesti suorituskykyyn [31] .
Kaksi ensimmäistä menetelmää antavat samanlaisen, mutta eivät identtisen vaikutuksen. Asiaa pahentaa vielä se, että funktiota määriteltäessä käytetty lause voi näyttää hyvin samanlaiselta kuin funktion määrittely: ensinnäkin avainsanan perässä functionvoi olla tunniste [Specification 20] , toiseksi puolipiste voidaan jättää pois merkkijonon täydennysmekanismin puolipisteiden vuoksi. [Spesifikaatio 8] . Esimerkki:
// funktion määritys funktion summa ( arg1 , arg2 ) { return arg1 + arg2 ; } // funktion määrittäminen lausekkeella var sum2 = funktion summa ( arg1 , arg2 ) { return arg1 + arg2 ; } funktiopalkki () { }; // käytä funktion määritystä ( funktiopalkki ( ){}) // käytä asianmukaista käskyäMerkittävin ero funktion määrittämisen ilmoituksen avulla ja funktion määrittämisen välillä lausekkeella on se, että edellisessä tapauksessa muuttujan luominen ja sen osoittaminen funktion arvoksi tapahtuu ennen koodin suorittamista, kun tulee suorituskonteksti. . Toisessa tapauksessa muuttuja saa alustajan arvon, kun osoituskäsky suoritetaan. Kun muuttuja luodaan saapuessaan suorituskontekstiin, se alustetaan arvolla undefined[Spec 21] [32] (katso lisätietoja Muuttujien ilmoitukset ).
Esimerkki, joka havainnollistaa koodin suoritusjärjestyksen eroa:
hälytys ( summa ( 3 , 4 )); // 7: summamuuttuja on jo luotu tämän rivin suoritushetkellä ja sille on määritetty funktio summa ( arg1 , arg2 ) funktio summa ( arg1 , arg2 ) { return arg1 + arg2 ; } hälytys ( summa2 ( 3 , 4 )); // virhe: muuttuja sum2 on jo luotu tämän rivin suoritushetkellä, mutta sille on määritetty määrittelemätön var sum2 = function ( arg1 , arg2 ) { return arg1 + arg2 ; };Toimintomäärityksiä ei pidä käyttää ehdollisten rakenteiden sisällä [33] , vaikka Gecko-selaimet käsittelevät tämän intuitiivisesti toteutetun funktiomekanismin avulla ohjeina [34] .
ToimintomäärityksetKoska ECMAScriptin funktiot ovat objekteja, eli ne ovat viitetietotyyppiä , funktioiden tunnisteet ovat muuttujia, jotka tallentavat viittauksen funktioon. Tämä voidaan havainnollistaa seuraavalla koodilla:
var summa = funktio ( arg1 , arg2 ) { return arg1 + arg2 ; }; hälytys ( summa ( 3 , 4 )); // 7 var sum2 = summa ; hälytys ( summa2 ( 4 , 2 )); // 6 summa = nolla ; hälytys ( summa2 ( 42 , 42 )); // 84()Korostetulla rivillä kannattaa kiinnittää huomiota siihen, että tehtävän oikealla puolella ei ole funktiokutsuoperaattoria ( ). Jos tällä rivillä ilmaistaisiin summan sijaan sum(), muuttujalle summa2 ei annettaisi funktiota, vaan sen kutsun tulos. Toinen huomionarvoinen asia on, että määrityksen jälkeen summa2 ei osoita funktion kopiota, vaan sitä funktiota, johon summa osoittaa .
Toimintojen ylikuormitusECMAScriptissä toimintojen ylikuormitus ei ole kielen ominaisuus, vaan sen vaikutus saadaan aikaan muiden mekanismien avulla.
Esimerkki toimintojen ylikuormituksen puuttumisesta:
funktion summa ( arg1 , arg2 ) { return arg1 + arg2 ; } funktion summa ( arg1 , arg2 , arg3 ) { return arg1 + arg2 + arg3 ; } hälytys ( summa ( 3 , 4 )); // NaN- hälytys ( summa ( 3 , 4 , 5 )); // 12Jos deklaroidaan useita samalla nimellä olevia funktioita, myöhemmät ilmoitukset korvaavat aiemmat ilmoitukset [31] .
Toimintojen ylikuormituksen vaikutus on kuitenkin saavutettavissa.
1. Tarkista, onko määrittämätön. Voit tarkistaa, onko varsinainen argumentti välitetty funktiolle, tarkistamalla muodollisen argumentin identiteetin arvolle undefined. Esimerkiksi:
funktion summa ( arg1 , arg2 , arg3 ) { if ( arg3 !== määrittelemätön ) { return arg1 + arg2 + arg3 ; } else { return arg1 + arg2 ; } } hälytys ( summa ( 3 , 4 )); // 7 hälytys ( summa ( 3 , 4 , 5 )); // 122. Tyyppitarkistus. Lisäksi , typeof, instanceofavulla constructorvoidaan selvittää todellisten argumenttien tyyppi ja mukauttaa funktion käyttäytymistä niiden mukaan.
funktion summa ( arg1 , arg2 , arg3 ) { kytkin ( arg3 tyyppi ) { case "undefined" : return arg1 + arg2 ; tapaus "numero" : return arg1 + arg2 + arg3 ; oletus : return arg1 + arg2 + " (" + arg3 + ")" ; } } hälytys ( summa ( 3 , 4 )); // 7 hälytys ( summa ( 3 , 4 , 5 )); // 12 hälytys ( summa ( 3 , 4 , "!" )); // "7 (!)"3. Pääsy tietoihin argumenteista. ECMAScript-funktioissa voit käyttää argumenttitietoja arguments[Specification 22] -objektin avulla . Erityisesti sen avulla voit käyttää indeksointia tiettyjen välitettyjen argumenttien [31] [35] ja ominaisuuden length, joka tallentaa todellisuudessa välitettyjen argumenttien määrän, käyttämiseen, mikä voi olla hyödyllistä yleistä ohjelmointiparadigmaa sovellettaessa .
funktion summa () { var res = 0 ; for ( var i = 0 ; i < argumentit . pituus ; i ++ ) { res += argumentit [ i ]; } return res ; } hälytys ( summa ( 3 , 4 )); // 7 hälytys ( summa ( 3 , 4 , 5 )); // 12 hälytys ( summa ( 3 , 4 , 5 , 7 , 9 )); // 28 RekursioECMAScript-funktioita voidaan kutsua rekursiivisesti. Kun määrität funktion käskyllä määrittämättä tunnistetta functionfunktion sisällä olevan avainsanan jälkeen, voit viitata siihen käyttämällä arguments[Specification 22] -objektin callee-ominaisuutta .
Esimerkki rekursiivisesta tekijälaskelmasta:
var factorial = funktio ( askel , res ) { res = res || 1 ; if ( askel < 2 ) { return res ; } palauttaa argumentit . callee ( vaihe -1 , vaihe * res ) ; }; hälytys ( faktoriaalinen ( 5 )); // 120Tällä hetkellä ECMAScript ei toteuta tail-rekursiota , jota käytetään rekursiivisten kutsujen optimointiin [36] .
TakaisinsoitotECMAScriptissä funktio on ensimmäisen luokan objekti ja se voidaan välittää argumenttina toiselle funktiolle. Jos sitä kutsutaan samanaikaisesti funktiossa, jolle se välitetään, niin sitä kutsutaan takaisinsoittofunktioksi (tai takaisinsoittofunktioksi ). Jos hyväksytyllä funktiolla ei ole nimeä, se on anonyymi takaisinsoittotoiminto ( anonyymi takaisinsoittotoiminto ) [37] . Tärkeimmät syyt takaisinsoittotoimintojen käyttöön ovat:
Esimerkki funktiosta, joka palauttaa hyväksytyn funktion suorittamisen tulosten summan argumenteille:
function sumOfResults ( takaisinsoitto ) { var tulos = 0 ; for ( var i = 1 ; i < argumentit . pituus ; i ++ ) { tulos += takaisinsoitto ( argumentit [ i ]); } palauttaa tuloksen ; } var square = funktio ( x ) { return x * x ; }; hälytys ( sumOfResults ( neliö , 3 , 4 )); // 25 SulkemisetECMAScriptin toiminnot ovat luonnostaan leksikaalisia. Tämä tarkoittaa, että laajuus määritellään funktion määrittelyhetkellä (toisin kuin dynaaminen alue, jossa laajuus määritellään funktiota kutsuttaessa) [39] .
Kun funktio on ilmoitettu, sisäkkäisten funktioiden laajuuksien sarja tallennetaan osaksi funktion tilaa. Toisin sanoen ohjelman suorituksen aikana toiminnot, joilla on pääsy sisäisten funktioiden paikallisiin muuttujiin, säilyttävät tällaisen pääsyn koko ohjelman suorituksen ajan [39] .
Sulkemismekanismilla voidaan rajoittaa muuttujien näkyvyyttä ohjelman erillisessä osassa, jotta ei synny nimiristiriitoja, kun ne jaetaan toisen koodin kanssa. Tätä varten koodi sijoitetaan anonyymiin funktioon, joka on varustettu toimintokutsuoperaattorilla.
( funktio () { // Ohjelman osa, jonka pääsy muuttujiin on eristettävä ulkopuolelta. })();Tässä tapauksessa ohjelmaosiossa määritellyt funktiot tulevat sisäkkäisiksi lisätyn anonyymin funktion suhteen ja on mahdollista päästä käsiksi anonyymin funktion paikallisiin muuttujiin (jotka olivat globaaleja ennen käyttöönottoa). Niihin ei kuitenkaan pääse käsiksi anonyymin funktion ulkopuolelta: funktion suorituksen tulos jätetään huomiotta.
Sulkemisia ei käytetä vain estämään pääsyä useisiin muuttujiin, vaan myös muuttamaan tällaista pääsyä. Tämä saavutetaan funktioilla, jotka palauttavat muita toimintoja. Esimerkki sarjanumerogeneraattoritoiminnosta:
var ainutlaatuinenId = funktio () { var id = 0 ; paluufunktio ( ) { paluutunnus ++ ; _ }; }(); var aArvo = ainutlaatuinenId (); var otherValue = ainutlaatuinenId ();Sulkemista käytettäessä vain funktiolla, joka on määritetty ainutlaatuiselleId- muuttujalle, on pääsy id -muuttujaan .
Curry esimerkki :
var multNumber = funktio ( arg ) { paluufunktio ( mul ) { return arg * mul ; _ }; }; var multFive = multNumber ( 5 ); hälytys ( multFive ( 7 )); //35Esimerkki kohteen luomisesta, jonka avulla voit käyttää ominaisuutta yksinomaan sen menetelmillä [40] :
var myObject = funktio () { var arvo = 0 ; return { lisäys : funktio ( inc ) { arvo += inc tyyppi === ' numero' ? sis .: 1 ; } , getValue : function ( ) { paluuarvo ; } } }(); hälytys ( myObject . arvo === määrittelemätön ); // tosi hälytys ( myObject . getValue ()); // 0 myObject . lisäys ( 9 ) myObject . lisäys ( 7 ) hälytys ( myObject . getValue ()); // 16Tämän tempun avulla voit emuloida vakioita sulkemisen avulla [41] .
var getConstant = funktio () { var vakiot = { UPPER_BOUND : 100 , LOWER_BOUND : - 100 }; paluufunktio ( vakioNimi ) { paluuvakiot [ vakioNimi ] ; _ }; }(); hälytys ( getConstant ( "LOWER_BOUND" )); // -100Perl 5 [Spec 23] vaikutti ECMAScriptin säännöllisten lausekkeiden syntaksiin ja toimivuuteen ja sallii kahdenlaisia syntaksia: literaalin ja objektin .
var literalWay = /pattern/ flags; var objectWay = uusi RegExp ( kuvio , liput );Ensimmäisessä tapauksessa malli ( pattern) ja liput ( flags) määritetään eksplisiittisesti ilman ylimääräisiä redundantteja syntaktisia merkkejä: vinoviivat toimivat niiden erottimina . Toisessa tapauksessa mallin ja lippujen tulee olla merkkijonoarvoja sisältäviä muuttujia tai suoraan merkkijonoarvoja. Kirjaimellinen merkintä on suositeltava, koska se ei vaadi säännöllisen lausekkeen metamerkkien kaksinkertaista [ ~ 2] pakottamista, toisin kuin objektimuoto [42] .
Seuraavia symboleja voidaan käyttää lippuina ECMAScriptissa:
Lippu | Kuvaus |
---|---|
g | g globaali tila: kuviota sovelletaan kaikkiin merkkijonon osumiin, säännöllinen lauseke ei pysähdy, kun mallin ensimmäinen vastaavuus on löydetty |
i | ja kirjainkoko - huomioimatta : sovitettaessa kuvion merkkien ja merkkijonojen kirjainkoko jätetään huomiotta |
m | monirivinen tila: rivinvaihtomerkkejä sisältävää riviä käsitellään useana rivinä, jotka on erotettu rivinvaihtomerkeillä; regex toimii kaikilla linjoilla |
Jokainen säännöllinen lauseke on objekti , jolla on seuraavat ominaisuudet:
Omaisuus | Tyyppi | Kuvaus |
---|---|---|
global | looginen | näyttää, onko lippu asetettug |
ignoreCase | looginen | näyttää, onko lippu asetettui |
multiline | looginen | näyttää, onko lippu asetettum |
lastIndex | numeerinen | vastaa paikkanumeroa merkkijonossa, josta kuvion vastaavuus löydettiin säännöllisen lausekkeen edellisen käytön seurauksena, tai 0, jos säännöllistä lauseketta ei ole käytetty aiemmin |
source | merkkijono | säännöllisen lausekkeen mallia vastaava merkkijono |
Lisäksi säännöllisille lausekkeille on määritetty seuraavat menetelmät:
Menetelmä | palautustyyppi | Kuvaus |
---|---|---|
exec(handledString) | objekti (taulukko) tainull | muodostaa joukon alimerkkijonoja, jotka vastaavat määritettyä mallia , ottaen huomioon määritetyt liput . nulljos mikään osamerkkijono ei vastaa kuviota |
test(handledString) | looginen | truejos on merkkijono, joka vastaa kuviota ja falsemuuten |
ECMAScript-objektit ovat järjestämättömiä ominaisuuksien kokoelmia , joissa jokaisessa on yksi tai useampi attribuutti , joka määrittää, kuinka ominaisuutta voidaan käyttää - esimerkiksi jos ReadOnly-attribuutin arvoksi on asetettu tosi , jokainen yritys suorittaa ECMAScript-koodia muuttaa kiinteistön arvo epäonnistuu.. Ominaisuudet ovat säiliöitä , jotka kapseloivat muita objekteja, primitiivityyppien arvoja ja menetelmiä [Specification 24] .
Nimi | Kuvaus |
---|---|
Lue ainoastaan | Omaisuus on vain luku -ominaisuus. Ohjelmassa tehty yritys muuttaa tämän omaisuuden arvoa jää turhaksi. Joissakin tapauksissa ReadOnly-attribuuttijoukon omaisuuden arvo muuttuu kielilaajennusympäristön toimintojen vuoksi, joten ReadOnlya ei pitäisi ymmärtää muuttumattomana. |
DontEnum | Kiinteistöä ei ole lueteltu silmukallafor-in |
Älä poista | Yritykset poistaa tämä ominaisuus ohitetaan. |
Sisäinen | Kiinteistö on sisäinen. Sillä ei ole nimeä, eikä sitä voi käyttää apuohjelmilla . Pääsy näihin ominaisuuksiin määräytyy kielen toteutuksen mukaan. |
ECMAScript-objektit on jaettu perusobjekteihin ( natiivi) ja laajennusobjekteihin (isäntä). Pohjalla tarkoitamme kaikkia objekteja, jotka ovat riippumattomia kielen laajennukseen liittyvästä ympäristöstä. Jotkut perusobjekteista ovat sisäänrakennettuja : olemassa ohjelman suorituksen alusta alkaen. Muita voidaan luoda ohjelman ollessa käynnissä. Laajennusobjektit tarjoavat ECMAScript-laajennus, ja ECMAScriptille tämä tarkoittaa, että ne ovat osa Document Object Model - tai Browser Object Model -mallia [Specification 3] .
SyntaksiObjektien määrittämiseen voidaan käyttää objekti- ja kirjaimellisia muotoja. Objektin määrittelyn objektimuodolla on samanlainen syntaksi kuin Java, mutta toisin kuin se, sulkuja ECMAScriptissä on käytettävä vain argumentteja välitettäessä konstruktorille [43] . Seuraavat merkinnät ovat syntaktisesti vastaavia:
varobj1 = uusi objekti ( ); var obj2 = uusi objekti ; var obj3 = {};Toista vaihtoehtoa ei kuitenkaan suositella [43] . Douglas Crockford suosittelee välttämään myös ensimmäistä vaihtoehtoa ja suosimaan kirjaimellista muotoa, jota hän pitää kielen suurena etuna [44] .
Kielimäärittely toimii objektin ominaisuuden käsitteen kanssa kutsuen menetelmää objektin ominaisuutena käytettäväksi funktioksi [Specification 3] .
Jokaisella kielen objektilla on seuraavat ominaisuudet:
Nimi | Lyhyt kuvaus |
---|---|
constructor | Objektin luomiseen käytetty funktio (yllä olevissa esimerkeissä se on Object()) |
hasOwnProperty(omaisuudenNimi) | Ilmaisee, onko annettu ominaisuus objektissa (ei sen prototyypissä ) |
isPrototypeOf(objekti) | Määrittää, onko objekti argumenttiobjektin prototyyppiketjussa |
propertyIsEnumerable(omaisuudenNimi) | Ilmaisee, onko ominaisuus, jolla on annettu nimi, numeroitavissa silmukassafor-in |
toString() | Palauttaa objektin merkkijonoesityksen |
jonkin arvo() | Palauttaa tämän arvon . Jos objekti on tulos kutsusta laajennusobjektin rakentajalle , arvo valueOf()on toteutuksesta riippuvainen [Spec 26] . Usein palautusarvo on objektia vastaava primitiivityyppinen arvo. Yleensä tämän menetelmän tulos on sama kuin toString(). Konstruktorilla luodut objektit Date() ovat hyvä esimerkki, jossa ja tulokset toString()eivät valueOf()täsmää [43] . |
Objektin ominaisuuksiin päästään käyttämällä piste- ja hakasulkumerkintää :
var obj = uusi objekti (); hälytys ( obj . konstruktori === obj [ "konstruktori" ]); // true - käytä piste- ja hakasulkumerkintää päästäksesi ominaisuuteen var foo = obj [ "toString" ]; // käyttämällä hakasulkeiden merkintää funktion tallentamiseen muuttujaan var result = obj [ "toString" ](); // funktiokutsun tuloksen tallentaminen muuttujahälytykseen ( foo ()); // tallennetun funktion kutsumisen tuloksen näyttäminen näytöllä hälytys ( tulos ); varboo = obj . _ toString ; // samanlainen pistemerkinnällä var res = obj . toString (); hälytys ( boo ()); hälytys ( res );Uusia ominaisuuksia voidaan asettaa dynaamisesti.
varcountry = uusi objekti ( ); maa [ "nimi" ] = "Venäjä" ; // käytä hakasulkumerkkiä maa . perustamisvuosi = 862 ; // käytä pistemerkintää var country2 = { "nimi" : "Venäjä" , "säätiön vuosi" : 862 }; // käytä kirjaimellista muotoaObjektien luominen edellisessä osiossa kuvatulla tavalla voi olla epäkäytännöllistä, koska koodia on monistettava [45] . Jos ohjelma käsittelee suurta määrää samantyyppisiä objekteja, kehittäjällä on mahdollisuus valita jokin kielessä käytetyistä tekniikoista [45] :
esinetehdas funktio, joka luo objektin ja palauttaa sen arvokseen, rakentaja funktio, joka muodostaa avainsanan thisavulla luomansa objektin ominaisuudet operaattorilla new, prototyyppinen lähestymistapa funktion ominaisuuden prototypekäyttäminen objektien yleisten ominaisuuksien näyttämiseen, sekoitettu lähestymistapa rakentaja-prototyyppi käyttämällä konstruktoria sellaisten objektien ominaisuuksien asettamiseen, jotka eivät ole menetelmiä, ja prototyyppilähestymistapaa menetelmien asettamiseen, dynaaminen prototyyppimenetelmä yhdistämällä konstruktori-prototyyppi -malliin perustuvaan objektien luomistoimintoon liittyvä koodi yhdeksi funktioksi varmistaen, että prototyypin ominaisuudet osoitetaan kerran, loiskonstruktorimenetelmä käyttää newobjektitehdastoiminnon kanssa.Kielessä ei ole luokkia , mutta niitä voidaan emuloida rakentajien avulla. Esimerkki luokan emuloinnista ECMAScriptissä:
function MyClass () { this . myArvo1 = 1 ; tämä . myArvo2 = 2 ; } Oma luokkani . prototyyppi . myMethod = function () { return this . myValue1 * tämä . myValue2 ; } var mc = uusi MyClass (); mc . myArvo1 = mc . myValue2 * 2 ; var i = mc . oma menetelmä ();Jokaisen objektin komponentin osalta voidaan ottaa huomioon periytyminen. Periessään vanhemman käyttöliittymää ilman, että lapsi käyttää esi-isän toiminnallisuutta, puhutaan käyttöliittymän periytymisestä. Periessään tilaa lapsiobjekti perii esi-olion tietorakenteen. Periessään toiminnallisuutta puhumme periytymisestä käyttöliittymän ja menetelmäkoodin ohella. Pääsääntöisesti tämä edellyttää tilaperinnön järjestämistä, mikä tekee järkeväksi yhdistää tilaperinnön ja toiminnallisuuden periytymisen toteutusperinnöksi [46] .
ECMAScriptin osalta vain rajapinnan periytymistä ei sovelleta, koska kielen funktioilla ei ole allekirjoituksia [45] .
Kielen tarjoamia mahdollisuuksia perinnön järjestämiseen voidaan arvioida esimerkiksi Stoyan Stefanovin [47] luettelosta kahdestatoista eri perinnön järjestämistavasta.
ES6:n käyttöönotto on eliminoinut monia JavaScript-ongelmien luokkia [48] [49] [50] [51] .
ECMAScript | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Murteet |
| ||||||||||||
Moottorit ( vertailu ) |
| ||||||||||||
Kehykset , kirjastot |
| ||||||||||||
Ihmiset | |||||||||||||
muu |
|
Ecma kansainväliset standardit | |
---|---|
ISO- standardit | |
---|---|
| |
1-9999 _ _ |
|
10 000 - 19999 |
|
20 000+ | |
Katso myös: Luettelo artikkeleista, joiden otsikot alkavat sanalla "ISO" |