ECMAScript | |
---|---|
Clasa de limba | Specificații pentru limbaje de programare , limbaj de programare funcțional și limbaj de programare multiparadigmă |
Aparut in | iunie 1997 |
Autor | Brendan Eich și Ecma International |
Dezvoltator | Brendan Eich |
Extensie de fișier | .es[2] |
Eliberare | ECMAScript 2022 [Spec 1] (iunie 2022 ) |
Tip sistem | rață |
Dialectele | JavaScript , JScript , ActionScript , JScript.NET , QtScript |
A fost influențat | Self [1] , C , Scheme [1] , Perl [1] , Python , Java [1] , AWK [1] |
influențat | Obiectiv-J |
Site-ul web | ecma-international.org _ |
ECMAScript este un limbaj de programare încorporabil, extensibil, fără I/O , folosit ca bază pentru construirea altor limbaje de scripting [3] .
ECMAScript este standardizat de organizația internațională ECMA în specificația ECMA-262 . Extensii de limbaj: JavaScript , JScript și ActionScript .
Limbajul provine din mai multe tehnologii, dintre care cele mai faimoase sunt limbajele JavaScript și JScript . Dezvoltarea primei revizuiri a specificației a început în noiembrie 1996. Specificația a fost adoptată în iunie 1997. Trimis la ISO/IEC JTC 1 pentru acceptare Fast-Tracking , acesta a servit drept bază pentru standardul internațional ISO/IEC 16262 . În iunie 1998, adunarea generală ECMA a adoptat cea de-a doua ediție a ECMA-262, corespunzătoare ISO/IEC 16262. A treia ediție a specificației a fost diferită de cea anterioară prin introducerea suportului pentru expresii regulate, îmbunătățirea suportului șirurilor, introducerea de noi structuri de control , un mecanism de excepție, formatarea la introducerea numerică și alte modificări[Specificație 2] .
Cinci tipuri de date primitive sunt acceptate în ECMAScript :
Tipul de date numerice din ECMAScript corespunde formatului de număr în virgulă mobilă pe 64 de biți definit de standardul IEEE 754-2008 , cu excepția faptului că diferitele valori Not-a-Number definite în standardul [4] sunt reprezentate în limba respectivă. prin valoarea specială unică NaN [ Specificația 4] .
Tipurile de date nule și nedefinite sunt denumite în mod informal tipuri „triviale” de David Flanagan , deoarece fiecare dintre ele definește o singură valoare [5] .
Limbajul are, de asemenea, un tip de date „compozit” [5] :
Pe lângă cele șase tipuri de date enumerate, ECMAScript acceptă încă șapte care sunt utilizate exclusiv pentru a stoca rezultate intermediare ale expresiilor evaluate:
Popularitatea limbajului JavaScript și non-trivialitatea procesării datelor de diferite tipuri au condus la desfășurarea cercetărilor academice în domeniul analizării tipurilor de date ECMAScript, care își propune să creeze un analizor de cod cu drepturi depline care ar putea fi utilizat în dezvoltarea integrată. medii [6] .
Există cincisprezece tipuri diferite de instrucțiuni în ECMAScript, care sunt enumerate în tabelul de mai jos:
Tipuri de instrucțiuni definite de specificația limbii [Specificația 7]Nume | numele original | Informatie scurta | Finala; [Specificația 8] |
---|---|---|---|
bloc | Engleză bloc | [[<instrucțiuni>]} | − |
Declarație variabilă | Engleză VariableStatement | var <lista declarațiilor de variabile> | + |
Instrucțiune goală | Engleză EmptyStatement | ; | + |
Expresie | Engleză ExpressionStatement | [șir la ∉ {{, funcție}] instrucțiune | + |
Condiție | Engleză IfStatement | if (<инструкция>) <выражение>[ else <выражение>] | − |
Ciclu | Engleză IterationStatement | do <expresie> while (<instrucțiune>) while (<instrucțiune>) <expresie> |
+/− [~1] |
Continuare | Engleză ContinueStatement | continua [<identificator>] | + |
Întrerupe | Engleză BreakStatement | break [<identificator>] | + |
Întoarcere | Engleză ReturnStatement | returnează [<instrucțiuni>] | + |
Combinaţie | Engleză WithStatement | cu (<instrucțiune>) <expresie> | − |
Eticheta | Engleză LabeledStatement | <identificator>: <expresie> | − |
Alegere | Engleză SwitchStatement | switch (<instrucțiune>) case <instrucțiune>: [<expresii>][ case <instrucțiune>: [<expresii>] ...] [implicit: [<expresii>]] | − |
Lansarea unei excepții | Engleză ThrowStatement | arunca <instruire> | + |
încercați să blocați | Engleză TryStatement | încercați <block> catch (<identificator>) <block> try <block> finally <block> try <block> catch (<identifier>) <block> finally <block> |
− |
(nou [Spec 9] ) Depanator | Engleză Depanator | depanator | − |
În ciuda punctului și virgulă obligatoriu în cazurile notate în coloana a patra, caietul de sarcini declară un mecanism de completare automată a șirurilor cu punct și virgulă , ceea ce duce la faptul că, dacă există o întrerupere de linie, instrucțiunea dinaintea întreruperii de linie poate fi echipată cu acest semn [ Specificația 8] , care face obiectul criticii [ 7 ] .
Instrucțiuni care își schimbă sensul atunci când se utilizează o linie nouă în [Specificație 8]Un exemplu de schimbare a sensului unei instrucțiuni
return { status : "complet" };Aici, linia evidențiată conține o instrucțiune valabilă după limbaj și, din moment ce urmează o nouă linie, este declanșat mecanismul de completare automată a liniilor cu punct și virgulă. În loc ca funcția care conține codul de mai sus să returneze un obiect cu proprietatea ca valoare status, va reveni undefined.
Deși forma literală a unui obiect nu este un bloc de cod, parantezele uniforme pot duce la erori. Dezvoltarea sau adoptarea unui standard de codificare adecvat poate reduce probabilitatea apariției acestora . Alegerea stilului de indentare joacă un rol important . În special, stilurile Allman și Whitesmith , precum și stilul Horstman și stilul GNU pentru codul JavaScript, sunt depreciate de majoritatea ghidurilor [8] , spre deosebire de stilurile K&R , 1TBS , BSD KNF .
Eroare de completare automatăDacă expresia scrisă pe linia următoare poate fi sintactic o continuare a expresiei de pe linia anterioară, mecanismul de completare automată a liniilor cu punct și virgulă nu funcționează [9] .
func () [ 'h1' , 'h2' ]. forEach ( funcție ( t ) { handleTag ( t ) })În acest exemplu, parantezele pătrate de pe a doua linie sunt interpretate ca referindu-se la un element de matrice returnat de func(). Virgula între paranteze este tratată ca operatorul corespunzător care returnează „h2”. Deci, codul este convertit în următoarele:
func ()[ 'h2' ]. forEach ( function ( t ) { handleTag ( t ); });Este obișnuit în standardele de codificare să se solicite punct și virgulă chiar dacă sintaxa limbajului permite omiterea lor [Standarde de codificare 1] [Standarde de codificare 2] [Standarde de codificare 3] [Standarde de codificare 4] [Standarde de codare 5] .
Blocuri și domeniul de aplicareO altă caracteristică a ECMAScript în raport cu alte limbaje asemănătoare C este că în acest limbaj blocurile nu formează un domeniu de aplicare . Variabilele declarate într-un bloc se aplică întregii funcții care conține blocul [10] [11] .
În această secțiune de cod, variabila este re-declarată în liniile evidențiate:
function foo ( ) { varsum = 0 ; pentru ( var i = 0 ; i < 42 ; i += 2 ) { var tmp = i + 2 ; suma += i * tmp ; } pentru ( var i = 1 ; i < 42 ; i += 2 ) { sum += i * i ; } alertă ( tmp ); suma returnata ; _ } foo ();În plus, variabila tmp declarată în prima dintre bucle (linia 4) este legală pentru a avea acces din afara buclei (linia 10) conform sintaxei limbajului.
Datorită naturii domeniului și blocurilor, se recomandă declararea variabilelor la începutul funcțiilor pentru a menține calitatea codului sursă [10] [Standarde de codare 1] [Standarde de codare 4] .
Declarații variabileVariabilele sunt definite folosind cuvinte cheie var, let, const. La declararea unei variabile, aceasta este plasată în domeniul corespunzător în cazul unei varfuncții, și în cazul let, constunui bloc de cod. Dacă o variabilă este declarată în afara funcțiilor, aceasta este plasată în domeniul global. Crearea unei variabile are loc atunci când se primește controlul funcției cu declarația acesteia. Sau un program dacă variabila este globală. Când o variabilă este creată în ECMAScript, aceasta capătă valoarea undefined. Dacă o variabilă este declarată cu inițializare , inițializarea are loc nu în momentul creării variabilei, ci atunci când linia cu instrucțiunea var[Specificație 10] este executată .
Când decomentați linia selectată, ecranul va afișa nu un număr , ci nedefinit :
var a = 42 ; function foo () { alert ( typeof a ); // var a = 10; } foo ();Când o variabilă este creată, aceasta dobândește proprietatea internă {DontDelete} și nu poate fi ștearsă folosind operatorul delete[Specificație 10] . Excepție fac variabilele declarate în context eval[12] [Specificație 11] .
Multe surse [13] [14] [15] [16] [17] [18] declară posibilitatea de a declara implicit variabile în ECMAScript atunci când se atribuie unui identificator valid care nu este un argument de funcție formală fără declararea mai întâi cu var. Totuși, în terminologia specificației limbajului, în acest caz este creată o proprietate a obiectului global, nu o variabilă [12] [Specificație 10] .
Fixarea în standardul de codificare a necesității de a declara variabile înainte de a fi utilizate [Coding Standards 1] [Coding Standards 4] (sau fixarea necesității de a folosi spații de nume pentru toate obiectele globale [Coding Standards 2] ) evită erorile subtile, prevenind pericolul interacțiunea variabilelor denumite identic în diferite părți ale codului [19] .
Următoarele cuvinte sunt cuvinte cheie în limbă și nu pot fi folosite ca identificatori [Spec. 12] :
break do instanceof typeof caz else nou var prinde în cele din urmă întoarce gol continuați pentru comutare în timp ce funcția de depanare aceasta cu implicit dacă se aruncă șterge în încercareÎn comparație cu ediția a treia a specificației [Specificația 13] , ediția a cincea a adăugat un cuvânt cheie debuggercu instrucțiunea corespunzătoare.
Următoarele cuvinte sunt folosite ca cuvinte cheie în extensiile propuse și, prin urmare, sunt rezervate pentru capacitatea de a adapta aceste extensii [Specificația 14] :
clasa enumerare se extinde super const export importCând utilizați modul strict, următoarele cuvinte sunt tratate ca rezervate pentru utilizare ulterioară [Spec 14] :
instrumentele lasă să producă randament public privat pachet de interfață protejat staticAstfel, comparativ cu ediția a treia a specificației de limbă, numărul de cuvinte rezervate pentru utilizare ulterioară a scăzut semnificativ. Anterior, existau 31 [Specificație 15] , iar prezența unui număr mare de cuvinte cheie și cuvinte rezervate, dintre care majoritatea nu sunt folosite în limbaj, a fost criticată [20] .
ECMAScript are atât operatori care folosesc cuvinte cheie ca nume, cât și operatori care folosesc semne de punctuație ca nume .
Clasificarea operatorilorÎn ordinea descrescătoare a priorității , operatorii ECMAScript pot fi împărțiți în următoarele grupuri:
Operatorii ++, --, -, +, ~, !, delete, typeof, void, ?:, =, *=, /=, +=, -=, <<=, >=, >>>=, &=, ^=, sunt |=asociativi de dreapta (adică sunt a op b op cechivalenti cu a op (b op c)). Operatorii ECMAScript rămași sunt lăsați asociativi [22] .
După arity , operatorii ECMAScript sunt împărțiți în următoarele grupuri:
În funcție de poziția semnului operației față de operanzi, operatorii ECMAScript sunt împărțiți în următoarele grupuri:
Operatorii sunt clasificați și după tipul de operanzi [25] și după natura acțiunii efectuate.
Caracteristicile instrucțiunilor ECMAScriptNu există niciun operator în ECMAScript care să vă permită să verificați dacă o proprietate aparține direct unui obiect sau este moștenită. Această verificare se efectuează folosind hasOwnProperty(). Datorită faptului că această metodă nu este un operator, poate fi suprascrisă de orice altă proprietate [26] .
Operatorul +este singurul operator aritmetic din limbaj care este supraîncărcat pentru argumente șir. Dacă cel puțin unul dintre operanzi este un șir, +acesta acționează ca un concatenator , în caz contrar efectuează adunarea [27] [Specificație 17] .
Spre deosebire de limbaje în care void este un tip de date, în ECMAScript este un operator care returnează o valoare undefined[28] .
Operatorul ==verifică egalitatea conform unui algoritm format din 10 pași, implicând în unele cazuri conversie de tip [Specificație 18] , care, în cele din urmă, poate duce la rezultate neevidente [29] .
Un exemplu de rezultate ale lucrării ==(în toate cazurile enumerate, valoarea operatorului ===cu aceleași argumente va fi false):
alertă ( "NaN" == NaN ); // alertă falsă ( NaN == NaN ); // alertă falsă ( adevărat == 1 ); // alertă adevărată ( adevărat == 42 ); // alertă falsă ( null == 0 ); // alertă falsă ( 0 == "" ); // alertă adevărată ( "" == 0 ); // alertă adevărată ( "fals" == fals ); // alertă falsă ( fals == 0 ); // alertă adevărată ( nedefinit == fals ); // alertă falsă ( null == fals ); // alertă falsă ( nedefinit == null ); // alertă adevărată ( " \t\r\n " == 0 ); // AdevăratFuncțiile din ECMAScript sunt obiecte [30] [31] . Constructorul cu care sunt create este Function(). Funcțiile, ca orice alte obiecte, pot fi stocate în variabile, obiecte și matrice, pot fi transmise ca argumente altor funcții și pot fi returnate de funcții. Funcțiile, ca orice alte obiecte, pot avea proprietăți. O caracteristică specifică esențială a funcțiilor este că acestea pot fi numite [30] .
Definirea funcțiilorExistă două tipuri de funcții în ECMAScript:
Funcțiile interne sunt obiecte încorporate (vezi mai jos ), nu neapărat implementate în ECMAScript [Specificație 19] .
În textul programului, o funcție numită în ECMAScript poate fi definită în unul dintre următoarele moduri:
// declararea funcției function sum ( arg1 , arg2 ) { return arg1 + arg2 ; } // definirea unei funcții folosind o instrucțiune var sum2 = function ( arg1 , arg2 ) { return arg1 + arg2 ; }; // definirea unei funcții folosind notația obiect var sum3 = new Function ( "arg1" , "arg2" , "return arg1 + arg2;" );Această din urmă metodă este cea mai puțin preferată, deoarece de facto se rezumă la definirea unei funcții folosind o expresie, dar în același timp generează o interpretare dublă a codului (o interpretare suplimentară are loc atunci când codul este transmis constructorului), care poate afecta negativ performanța [31] .
Primele două metode dau un efect similar, dar nu identic. Pentru a înrăutăți lucrurile, declarația folosită la definirea unei funcții poate arăta foarte asemănătoare cu o declarație de funcție: în primul rând, cuvântul cheie functionpoate fi urmat de un identificator [Specificație 20] , în al doilea rând, punct și virgulă poate fi omis datorită mecanismului de completare a șirurilor de caractere și virgulă. [Specificația 8] . Exemplu:
// declararea funcției function sum ( arg1 , arg2 ) { return arg1 + arg2 ; } // definirea unei funcții folosind o expresie var sum2 = function sum ( arg1 , arg2 ) { return arg1 + arg2 ; } bara de funcții () { }; // folosiți declarația funcției ( bara de funcții (){}) // folosiți instrucțiunea corespunzătoareCea mai semnificativă diferență între definirea unei funcții folosind o declarație și definirea unei funcții folosind o expresie este că, în primul caz, crearea unei variabile și atribuirea acesteia ca valoare a funcției are loc înainte ca codul să fie executat la intrarea în contextul de execuție. . În al doilea caz, variabila primește valoarea inițializatorului atunci când este executată instrucțiunea de atribuire. Când o variabilă este creată la intrarea într-un context de execuție, aceasta este inițializată cu valoarea undefined[Spec 21] [32] (a se vedea Declarațiile de variabile pentru detalii ).
Un exemplu care ilustrează diferența în ordinea de execuție a codului:
alertă ( suma ( 3 , 4 )); // 7: variabila sum a fost deja creată în momentul în care această linie este executată, iar funcția sum ( arg1 , arg2 ) i-a fost atribuită funcția sum ( arg1 , arg2 ) { return arg1 + arg2 ; } alertă ( suma2 ( 3 , 4 )); // eroare: variabila sum2 a fost deja creată în momentul în care această linie este executată, dar undefined i-a fost atribuit var sum2 = function ( arg1 , arg2 ) { return arg1 + arg2 ; };Declarațiile de funcții nu ar trebui utilizate în cadrul constructelor condiționate [33] , deși browserele Gecko vor gestiona acest lucru intuitiv prin mecanismul implementat de funcții ca instrucțiuni [34] .
Atribuții de funcțiiDeoarece funcțiile din ECMAScript sunt obiecte, adică sunt de tip de date de referință , identificatorii de funcție sunt variabile care stochează o referință la funcție. Acest lucru poate fi ilustrat cu următorul cod:
var sum = function ( arg1 , arg2 ) { return arg1 + arg2 ; }; alertă ( suma ( 3 , 4 )); // 7 var sum2 = sum ; alertă ( suma2 ( 4 , 2 )); // 6 sumă = nul ; alertă ( sum2 ( 42 , 42 )); // 84În rândul evidențiat, ar trebui să acordați atenție absenței operatorului de apelare a funcției ( ()) din partea dreaptă a misiunii. Dacă în loc de sum ar fi indicat în această linie sum(), variabilei sum2 nu i s-ar atribui o funcție, ci rezultatul apelului acesteia. Un alt lucru demn de remarcat este că după atribuire, sum2 nu indică o copie a funcției, ci chiar funcția către care sum indică .
Supraîncărcarea funcțieiÎn ECMAScript , supraîncărcarea funcțiilor nu este o proprietate a limbajului, dar efectul său este furnizat prin utilizarea altor mecanisme.
Un exemplu care arată absența supraîncărcării funcției:
function sum ( arg1 , arg2 ) { return arg1 + arg2 ; } function sum ( arg1 , arg2 , arg3 ) { return arg1 + arg2 + arg3 ; } alertă ( suma ( 3 , 4 )); // Alertă NaN ( suma ( 3 , 4 , 5 )); // 12Dacă sunt declarate mai multe funcții cu același nume, declarațiile ulterioare suprascrie declarațiile anterioare [31] .
Cu toate acestea, efectul supraîncărcării funcțiilor este realizabil.
1. Verificați pentru nedefinit. Pentru a verifica dacă argumentul real a fost transmis funcției, puteți verifica argumentul formal pentru identitate la valoarea lui undefined. De exemplu:
function sum ( arg1 , arg2 , arg3 ) { if ( arg3 !== nedefinit ) { return arg1 + arg2 + arg3 ; } else { return arg1 + arg2 ; } } alertă ( suma ( 3 , 4 )); // 7 alertă ( suma ( 3 , 4 , 5 )); // 122. Verificare tip. În plus, typeof, instanceof, constructorpoate fi folosit pentru a afla tipul de argumente reale și pentru a personaliza comportamentul funcției în funcție de acestea.
function sum ( arg1 , arg2 , arg3 ) { comutator ( tipul arg3 ) { case " nedefinit" : return arg1 + arg2 ; caz „număr” : returnează arg1 + arg2 + arg3 ; implicit : return arg1 + arg2 + " (" + arg3 + ")" ; } } alertă ( suma ( 3 , 4 )); // 7 alertă ( suma ( 3 , 4 , 5 )); // 12 alertă ( suma ( 3 , 4 , "!" )); // "7 (!)"3. Acces la date despre argumente. În funcțiile ECMAScript, puteți accesa date argument folosind obiectul arguments[Specificație 22] . În special, vă permite să utilizați indexarea pentru a accesa argumente specifice transmise [31] [35] și o proprietate lengthcare stochează numărul de argumente transmise efectiv, ceea ce poate fi util atunci când se aplică paradigma de programare generică .
function sum () { var res = 0 ; pentru ( var i = 0 ; i < argumente . lungime ; i ++ ) { res += argumente [ i ]; } return res ; } alertă ( suma ( 3 , 4 )); // 7 alertă ( suma ( 3 , 4 , 5 )); // 12 alertă ( suma ( 3 , 4 , 5 , 7 , 9 )); // 28 RecursiuneFuncțiile ECMAScript pot fi apelate recursiv. Când definiți o funcție folosind o instrucțiune fără a specifica un identificator după cuvântul cheie functiondin interiorul funcției, vă puteți referi la aceasta folosind proprietatea apelat a obiectului arguments[Specificație 22] .
Un exemplu de calcul factorial recursiv:
var factorial = function ( step , res ) { res = res || 1 ; if ( pas < 2 ) { return res ; } returnează argumente . apelat ( pas - 1 , pas * res ); }; alertă ( factorial ( 5 )); // 120În prezent, ECMAScript nu implementează recursiunea coadă , care este folosită pentru a optimiza apelurile recursive [36] .
Apeluri inverseÎn ECMAScript, o funcție este un obiect de primă clasă și poate fi transmisă ca argument unei alte funcții. Dacă în același timp este apelat în funcția la care este transmis, atunci se numește funcție de apel invers (sau funcție de apel invers ). Dacă funcția transmisă nu are un nume, este o funcție de apel invers anonim ( funcție de apel invers anonim ) [37] . Principalele motive pentru utilizarea funcțiilor de apel invers sunt:
Un exemplu de funcție care returnează suma rezultatelor executării funcției transmise pe argumente:
function sumOfResults ( callback ) { var rezultat = 0 ; pentru ( var i = 1 ; i < argumente . lungime ; i ++ ) { rezultat += callback ( argumente [ i ]); } returnează rezultatul ; } var pătrat = function ( x ) { return x * x ; }; alertă ( sumOfResults ( pătrat , 3 , 4 )); // 25 ÎnchideriFuncțiile din ECMAScript sunt în mod inerent acoperite lexical. Aceasta înseamnă că domeniul de aplicare este definit în momentul în care funcția este definită (spre deosebire de domeniul dinamic, unde domeniul de aplicare este definit în momentul în care funcția este apelată) [39] .
Atunci când o funcție este declarată, secvența de domenii ale funcției imbricate este stocată ca parte a stării funcției. Adică, în timpul execuției programului, funcțiile care au acces la variabilele locale ale funcțiilor înglobate păstrează un astfel de acces pe parcursul execuției programului [39] .
Mecanismul de închidere poate fi folosit pentru a restricționa vizibilitatea variabilelor într-o secțiune autonomă a programului, astfel încât să nu existe conflicte de nume atunci când sunt partajate cu alt cod. Pentru a face acest lucru, codul este plasat într-o funcție anonimă, prevăzută cu un operator de apelare a funcției.
( funcția () { // Secțiunea programului al cărei acces la variabile trebuie izolat din exterior. })();În acest caz, funcțiile definite în secțiunea program devin imbricate în raport cu funcția anonimă adăugată și este posibil să se acceseze variabilele locale ale funcției anonime (care erau globale înainte de introducerea acesteia). Totuși, acestea nu pot fi accesate din afara funcției anonime: rezultatul execuției funcției este ignorat.
Închiderile sunt folosite nu numai pentru a interzice accesul la o serie de variabile, ci și pentru a modifica un astfel de acces. Acest lucru se realizează cu funcții care returnează alte funcții. Un exemplu de funcție de generare a numărului de serie:
var uniqueId = function () { var id = 0 ; return function () { return id ++ ; }; }(); var aValue = uniqueId (); var anotherValue = uniqueId ();Folosind o închidere , numai funcția care a fost atribuită variabilei uniqueId are acces la variabila id .
Exemplu de curry :
var multNumber = function ( arg ) { return function ( mul ) { return arg * mul ; }; }; var multFive = multNumber ( 5 ); alertă ( multFive ( 7 )); //35Un exemplu de creare a unui obiect care vă permite să accesați proprietatea exclusiv folosind metodele sale [40] :
var myObject = function () { var value = 0 ; return { increment : function ( inc ) { value += typeof inc === 'numar' ? inc : 1 ; }, getValue : function ( ) { return value ; } } }(); alertă ( myObject . value === nedefinit ); // alertă adevărată ( myObject . getValue ()); // 0 myObject . increment ( 9 ) myObject . increment ( 7 ) alert ( myObject . getValue ()); // 16Folosind acest truc, puteți folosi o închidere pentru a emula constante [41] .
var getConstant = function () { var constante = { UPPER_BOUND : 100 , LOWER_BOUND : - 100 }; return function ( constantName ) { return constants [ constantName ]; }; }(); alertă ( getConstant ( "LOWER_BOUND" )); // -100Sintaxa și funcționalitatea expresiilor regulate în ECMAScript a fost influențată de Perl 5 [Spec 23] și permite două tipuri de sintaxă: literal și obiect .
var literalWay = /pattern/flags; var objectWay = new RegExp ( model , steaguri );În primul caz, șablonul ( pattern) și steagurile ( flags) sunt specificate în mod explicit, fără semne sintactice redundante suplimentare: barele oblice servesc drept separatori . În al doilea caz, șablonul și steagurile trebuie să fie variabile care conțin valori șir sau direct valori șir. Notația literală este preferată prin faptul că nu necesită dubla [~ 2] evadare a metacaracterelor expresiei regulate, spre deosebire de forma obiectului [42] .
Următoarele simboluri pot fi folosite ca steaguri în ECMAScript:
Indicatori de expresie regulată [42] [Spec. 23]Steag | Descriere |
---|---|
g | g modul global: modelul este aplicat tuturor potrivirilor din șir, expresia regulată nu se oprește după ce este găsită prima potrivire a modelului |
i | și majuscule - ignorare : la potrivire, caracterele și șirurile de caractere ale modelului sunt ignorate |
m | modul cu mai multe rânduri : o linie care conține caractere de nouă linie este tratată ca mai multe linii separate prin caractere de avans de linie; regex funcționează pe toate liniile |
Fiecare expresie regulată este un obiect cu următoarele proprietăți:
Proprietățile obiectului expresiei regulate ECMAScript [42] [Specificație 23]Proprietate | Tip de | Descriere |
---|---|---|
global | logic | arată dacă steagul este setatg |
ignoreCase | logic | arată dacă steagul este setati |
multiline | logic | arată dacă steagul este setatm |
lastIndex | numeric | se potrivește cu numărul de poziție din șirul în care a fost găsită potrivirea modelului ca urmare a aplicării anterioare a expresiei regulate sau 0 dacă expresia regulată nu a fost aplicată anterior |
source | şir | șir care se potrivește cu modelul expresiei regulate |
În plus, următoarele metode sunt definite pentru expresiile regulate:
Metode de obiect expresie regulată în ECMAScript [42] [Specificație 23]Metodă | tip de returnare | Descriere |
---|---|---|
exec(handledString) | obiect (matrice) saunull | formează o matrice de subșiruri care se potrivesc cu modelul specificat , ținând cont de steaguri setate . nulldacă niciun subșir nu se potrivește cu modelul |
test(handledString) | logic | truedacă există un șir care se potrivește cu modelul și falsealtfel |
Obiectele ECMAScript sunt colecții neordonate de proprietăți , fiecare dintre ele având unul sau mai multe atribute care determină modul în care poate fi utilizată proprietatea - de exemplu, dacă valoarea atributului ReadOnly este setată la true , atunci orice încercare de executare a codului ECMAScript de a modifica valoarea proprietății respective va eșua. Proprietățile sunt containere care încapsulează alte obiecte, valori ale tipurilor primitive și metode [Specificație 24] .
Atributele proprietății obiectului ECMAScript [Spec. 25]Nume | Descriere |
---|---|
numai citire | Proprietatea este o proprietate numai în citire. O încercare de a schimba valoarea acestei proprietăți, făcută în program, va rămâne zadarnică. În unele cazuri, valoarea unei proprietăți cu setul de atribute ReadOnly se modifică din cauza acțiunilor mediului de extensie a limbajului, astfel încât ReadOnly nu trebuie înțeles ca imuabil. |
DontEnum | Proprietatea nu este enumerată prin buclăfor-in |
Nu șterge | Încercările de a elimina această proprietate vor fi ignorate. |
Intern | Proprietatea este interioara. Nu are nume și nu poate fi accesat cu accesorii . Accesul la aceste proprietăți este determinat de implementarea limbajului. |
Obiectele ECMAScript sunt împărțite în obiecte de bază (native) și extensii (gazdă). Prin bază înțelegem orice obiecte care sunt independente de mediu legate de extinderea limbajului. Unele dintre obiectele de bază sunt încorporate -in: există încă de la începutul execuției programului. Altele pot fi create atunci când programul rulează. Obiectele de extensie sunt furnizate de extensia ECMAScript, iar pentru ECMAScript acest lucru înseamnă că fac parte din Modelul obiectului document sau Modelul obiectului browser [Specificație 3] .
SintaxăFormele obiect și literale pot fi folosite pentru a specifica obiecte. Forma obiect de specificare a unui obiect are o sintaxă similară cu Java, dar, spre deosebire de aceasta, parantezele din ECMAScript sunt necesare pentru a fi folosite numai atunci când se transmit argumente unui constructor [43] . Următoarele intrări sunt echivalente sintactic:
varobj1 = obiect nou ( ); var obj2 = obiect nou ; var obj3 = {};Totuși, a doua opțiune nu este recomandată [43] . Douglas Crockford recomandă evitarea și prima variantă, preferând forma literală, pe care o consideră a fi un mare avantaj al limbajului [44] .
Specificația limbajului funcționează cu conceptul de proprietate a unui obiect , denumind o metodă o funcție folosită ca proprietate a unui obiect [Specificație 3] .
Fiecare obiect din limbaj are următoarele proprietăți:
Proprietăți ale obiectelor ECMAScript [43]Nume | Scurta descriere |
---|---|
constructor | Funcția folosită pentru a crea obiectul (în exemplele de mai sus este Object()) |
areOwnProperty(PropertyName) | Indică dacă proprietatea dată există în obiect (nu în prototipul său ) |
isPrototypeOf(obiect) | Determină dacă un obiect se află în lanțul prototip al obiectului argument |
propertyIsEnumerable(propertyName) | Indică dacă proprietatea cu numele dat este enumerabilă în buclăfor-in |
toString() | Returnează reprezentarea în șir a obiectului |
valoarea() | Returnează această valoare . Dacă obiectul este rezultatul unui apel către constructorul unui obiect extensie , valoarea valueOf()este dependentă de implementare [Spec 26] . Adesea, valoarea returnată este o valoare de tip primitiv corespunzătoare unui obiect. De regulă, rezultatul acestei metode este același cu rezultatul toString(). Obiectele create cu un constructor Date() sunt un exemplu excelent în care rezultatele toString()și valueOf()nu se potrivesc [43] . |
Proprietățile obiectului sunt accesate folosind notația punct și paranteză :
var obj = obiect nou (); alert ( obj . constructor === obj [ "constructor" ]); // true - folosește notația punct și paranteze pentru a accesa proprietatea var foo = obj [ "toString" ]; // folosind notația paranteze pentru a stoca funcția într-o variabilă var result = obj [ "toString" ](); // salvează rezultatul apelului de funcție într-o alertă variabilă ( foo ()); // afișarea rezultatului apelării funcției stocate pe ecranul de alertă ( rezultat ); varboo = obj . _ toString ; // similar cu notația punct var res = obj . toString (); alertă ( huidu ()); alertă ( res );Noile proprietăți pot fi setate dinamic.
varcountry = obiect nou ( ); country [ "name" ] = "Rusia" ; // folosiți notația paranteze țara . Anul fundației = 862 ; // folosește notația cu puncte var country2 = { "nume" : "Rusia" , "FoundationYear" : 862 }; // folosiți forma literalăCrearea obiectelor în modul descris în secțiunea anterioară poate fi nepractică din cauza necesității de a duplica codul [45] . Dacă programul manipulează un număr mare de obiecte de același tip, dezvoltatorul are posibilitatea de a alege una dintre tehnicile utilizate în limbaj [45] :
fabrica de obiecte o funcție care creează un obiect și îl returnează ca valoare, constructor o funcție care folosește cuvântul cheie thispentru a forma proprietățile obiectului pe care îl creează folosind operatorul new, abordare prototip folosind proprietatea prototypeunei funcții pentru a afișa proprietățile generale ale obiectelor, abordare mixtă constructor-prototip folosind un constructor pentru a seta proprietăți ale obiectelor care nu sunt metode și o abordare prototip pentru a seta metode, metoda prototipului dinamic încheierea codului legat de funcția de a crea obiecte bazate pe abordarea mixtă constructor-prototip într-o singură funcție, asigurându-se că proprietățile prototipului sunt atribuite o singură dată, metoda constructorului parazitar utilizați newcu funcția de fabrică de obiecte.Nu există clase în limbaj , dar pot fi emulate folosind constructori. Un exemplu de emulare de clasă în ECMAScript:
function MyClass () { this . myValue1 = 1 ; aceasta . myValue2 = 2 ; } Clasa mea . prototip . myMethod = function () { return this . myValue1 * aceasta . myValue2 ; } var mc = new MyClass (); mc . myValue1 = mc . myValue2 * 2 ; var i = mc . myMethod ();Pentru fiecare dintre componentele obiectului se poate lua în considerare moștenirea. Când se moștenește interfața unui părinte fără ca copilul să folosească funcționalitatea strămoșului, se vorbește de moștenirea interfeței. Când moștenește starea, obiectul copil moștenește structura de date a obiectului strămoș. La moștenirea funcționalității, vorbim despre moștenire împreună cu interfața și codul metodelor. De regulă, aceasta implică necesitatea organizării moștenirii de stat, ceea ce face rezonabilă combinarea moștenirii de stat și moștenirea funcționalității în moștenirea implementării [46] .
În ceea ce privește ECMAScript, nu se aplică numai moștenirea interfeței, deoarece funcțiile din limbaj nu au semnături [45] .
Posibilitățile oferite de limbaj pentru organizarea moștenirii pot fi judecate, de exemplu, după lista dată de Stoyan Stefanov [47] a douăsprezece moduri diferite de organizare a moștenirii.
Adoptarea ES6 a eliminat multe clase de probleme JavaScript [48] [49] [50] [51] .
ECMAScript | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Dialectele | |||||||||||||
Motoare ( comparație ) | |||||||||||||
Cadre , biblioteci |
| ||||||||||||
oameni | |||||||||||||
Alte |
|
internaționale Ecma | Standardele|
---|---|
ISO | Standardele|
---|---|
| |
de la 1 la 9999 |
|
10000 până la 19999 |
|
20000+ | |
Vezi și: Lista articolelor ale căror titluri încep cu „ISO” |