Sintaxă JavaScript - JavaScript syntax
Sintaxa de JavaScript este un set de reguli care definesc un program JavaScript structurat corect.
Exemplele de mai jos folosesc funcția jurnal a obiectului consolă prezent în majoritatea browserelor pentru ieșirea textului standard .
Biblioteca standard JavaScript nu are o funcție oficială de ieșire a textului standard (cu excepția document.write). Având în vedere că JavaScript este utilizat în principal pentru scriptarea pe partea clientului în browserele web moderne și că aproape toate browserele Web oferă funcția de alertă , alerta poate fi de asemenea utilizată, dar nu este utilizată în mod obișnuit.
Origini
Brendan Eich a rezumat strămoșii sintaxei în primul paragraf al specificației JavaScript 1.1 după cum urmează:
JavaScript împrumută cea mai mare parte a sintaxei sale de la Java , dar moștenește și de la Awk și Perl , cu o anumită influență indirectă de la Self în sistemul său de prototip de obiect.
Noțiuni de bază
Sensibil la majuscule
JavaScript este sensibil la majuscule și minuscule . Este obișnuit să începeți numele unui constructor cu o literă cu majuscule și numele unei funcții sau variabile cu o literă minusculă.
Exemplu:
var a=5;
console.log(a); // 5
console.log(A); // throws a ReferenceError: A is not defined
Spațiu alb și punct și virgulă
Spre deosebire de C , spațiul alb din sursa JavaScript poate avea un impact direct asupra semanticii . Declarațiile de punct și virgulă în JavaScript. Datorită inserării automate de punct și virgulă (ASI), unele instrucțiuni care sunt bine formate atunci când se analizează o linie nouă vor fi considerate complete, ca și cum un punct și virgulă ar fi inserat chiar înainte de linia nouă. Unele autorități recomandă furnizarea punctelor și virgulelor care finalizează instrucțiunile, deoarece poate diminua efectele neintenționate ale inserării automate a punctelor și virgulelor.
Există două probleme: cinci jetoane pot începe fie o declarație, fie pot fi extensia unei declarații complete; și cinci producții restricționate, unde întreruperile de linie nu sunt permise în anumite poziții, ceea ce poate duce la o analiză incorectă.
Cele cinci jetoane problematice sunt paranteze deschise " ( ", paranteză deschisă " [ ", bară " / ", plus " + " și minus " - ". Dintre acestea, paranteza deschisă este comună în modelul de expresie a funcției invocate imediat , iar parantezele deschise apar uneori, în timp ce altele sunt destul de rare. Exemplul dat în specificație este:
a = b + c
(d + e).foo()
// Treated as:
// a = b + c(d + e).foo();
cu sugestia ca afirmația precedentă să fie terminată cu punct și virgulă.
Unii sugerează în schimb utilizarea de conducere semicoloane pe liniile incepand cu „ ( “ sau „ [ “, astfel încât linia nu este unit în mod accidental cu cel anterior. Acest lucru este cunoscut ca un punct și virgulă defensiv , și este deosebit de recomandată, deoarece codul poate deveni altfel ambiguă atunci când este rearanjat. De exemplu:
a = b + c
;(d + e).foo()
// Treated as:
// a = b + c;
// (d + e).foo();
Punctele și virgulele inițiale sunt, de asemenea, folosite uneori la începutul bibliotecilor JavaScript, în cazul în care sunt atașate la o altă bibliotecă care omite un punct și virgulă final, deoarece acest lucru poate duce la ambiguitatea declarației inițiale.
Cele cinci producții restricționate sunt return , throw , break , continue și post-increment / decrement. În toate cazurile, inserarea punctelor și virgulelor nu rezolvă problema, dar clarifică sintaxa analizată, facilitând detectarea erorii. returnează și aruncă ia o valoare opțională, în timp ce pauză și continuă ia o etichetă opțională. În toate cazurile, sfatul este să păstrați valoarea sau eticheta pe aceeași linie cu declarația. Acest lucru apare cel mai adesea în declarația return, unde s-ar putea returna un obiect mare literal, care ar putea fi plasat accidental începând de pe o nouă linie. Pentru post-creștere / descreștere, există o ambiguitate potențială cu pre-creștere / descreștere și, din nou, se recomandă păstrarea acestora pe aceeași linie.
return
a + b;
// Returns undefined. Treated as:
// return;
// a + b;
// Should be written as:
// return a + b;
Comentarii
Sintaxa comentariilor este aceeași ca în C ++ , Swift și multe alte limbi.
// a short, one-line comment
/* this is a long, multi-line comment
about my script. May it one day
be great. */
/* Comments /* may not be nested */ Syntax error */
Variabile
Variabilele din JavaScript standard nu au atașat niciun tip , astfel încât orice valoare (fiecare valoare are un tip) poate fi stocată în orice variabilă. Începând cu ES6 , cea de-a 6-a versiune a limbii, variabilele ar putea fi declarate cu varvariabilele cu scop de funcție și letsau constcare sunt pentru variabilele la nivel de bloc . Înainte de ES6, variabilele puteau fi declarate numai cu o varinstrucțiune. Valorile atribuite variabilelor declarate cu constnu pot fi modificate, dar proprietățile sale pot. Identificatorul unei variabile trebuie să înceapă cu o literă, subliniere ( _ ) sau semn de dolar ( $ ), în timp ce caracterele ulterioare pot fi, de asemenea, cifre ( 0-9 ). JavaScript distinge majuscule și minuscule, astfel încât caracterele majuscule "A" până la "Z" sunt diferite de caracterele minuscule "a" până la "z".
Începând cu JavaScript 1.5, literele ISO 8859-1 sau Unicode (sau secvențele de evadare \ uXXXX Unicode) pot fi utilizate în identificatori. În anumite implementări JavaScript, semnul at (@) poate fi utilizat într-un identificator, dar acest lucru este contrar specificațiilor și nu este acceptat în implementările mai noi.
Scoping și ridicare
Variabilele declarate cu varsunt vizate lexical la un nivel de funcție , în timp ce cele cu letsau constau un domeniu de nivel de bloc . Declarațiile sunt procesate înainte de executarea oricărui cod. Aceasta este denumită
ridicare și este echivalent cu variabilele care suntdeclarate înainteîn partea de sus a funcției sau a blocului.
Cu var, letși cu constdeclarații, numai declarația este ridicată; sarcinile nu sunt ridicate. Astfel, o declarație din mijlocul funcției este echivalentă cu o declarație de declarație în partea de sus a funcției și o instrucțiune de atribuire în acel punct din mijlocul funcției. Aceasta înseamnă că valorile nu pot fi accesate înainte de a fi declarate; trimiterea înainte nu este posibilă. Cu o variabilă, valoarea este până când este inițializată. Variabilele declarate cu sau nu pot fi accesate până la inițializare, deci referirea la variabilă va provoca o eroare.
var x = 1var xx = 1varundefinedletconst
Declarațiile de funcție, care declară o variabilă și îi atribuie o funcție, sunt similare cu instrucțiunile variabile, dar pe lângă ridicarea declarației, ele ridică și atribuirea - ca și cum întreaga instrucțiune ar fi apărut în partea de sus a funcției care conține - și astfel referința directă este, de asemenea, posibilă: locația unei instrucțiuni de funcție într-o funcție de închidere este irelevantă. Acest lucru este diferit de la o expresie funcție fiind atribuită unei variabile într - o var, letsau constdeclarație.
Deci, de exemplu,
var func = function() { .. } // declaration is hoisted only
function func() { .. } // declaration and assignment are hoisted
Scopul blocului poate fi produs prin înfășurarea întregului bloc într-o funcție și apoi executarea acestuia - acesta este cunoscut sub numele de model de expresie a funcției invocate imediat - sau prin declararea variabilei utilizând letcuvântul cheie.
Declarație și atribuire
Variabilele declarate în afara unui domeniu sunt globale . Dacă o variabilă este declarată într-un domeniu de aplicare superior, poate fi accesată de domeniile copil.
Când JavaScript încearcă să rezolve un identificator, acesta apare în domeniul local. Dacă acest identificator nu este găsit, acesta apare în următorul domeniu exterior și așa mai departe de-a lungul lanțului de domeniu până ajunge la domeniul global în care se află variabilele globale. Dacă tot nu este găsit, JavaScript va ridica o ReferenceErrorexcepție.
Când atribuiți un identificator, JavaScript parcurge exact același proces pentru a prelua acest identificator, cu excepția faptului că, dacă nu este găsit în domeniul global , va crea „variabila” în domeniul în care a fost creat. În consecință, o variabilă declarată niciodată nu va fi globală, dacă este atribuită. Declararea unei variabile (cu cuvântul cheie var) în domeniul global (adică în afara oricărui corp de funcție (sau bloc în cazul let / const)), atribuirea unui identificator niciodată declarat sau adăugarea unei proprietăți obiectului global (de obicei fereastră ) creați, de asemenea, o nouă variabilă globală.
Rețineți că modul strict JavaScript interzice alocarea unei variabile nedeclarate, ceea ce evită poluarea spațiului de nume global.
Exemple
Iată câteva exemple de declarații variabile și domeniul de aplicare:
var x1 = 0; // A global variable, because it is not in any function
let x2 = 0; // Also global, this time because it is not in any block
function f() {
var z = 'foxes', r = 'birds'; // 2 local variables
m = 'fish'; // global, because it wasn't declared anywhere before
function child() {
var r = 'monkeys'; // This variable is local and does not affect the "birds" r of the parent function.
z = 'penguins'; // Closure: Child function is able to access the variables of the parent function.
}
twenty = 20; // This variable is declared on the next line, but usable anywhere in the function, even before, as here
var twenty;
child();
return x1 + x2; // We can use x1 and x2 here, because they are global
}
f();
console.log(z); // This line will raise a ReferenceError exception, because the value of z is no longer available
for (let i = 0; i < 10; i++) console.log(i);
console.log(i); // throws a ReferenceError: i is not defined
for (const i = 0; i < 10; i++) console.log(i); // throws a TypeError: Assignment to constant variable
const pi; // throws a SyntaxError: Missing initializer in const declaration
Tipuri de date primitive
Limbajul JavaScript oferă șase tipuri de date primitive :
- Nedefinit
- Număr
- BigInt
- Şir
- Boolean
- Simbol
Unele dintre tipurile de date primitive oferă, de asemenea, un set de valori numite care reprezintă extinderea limitelor tipului. Aceste valori numite sunt descrise în secțiunile corespunzătoare de mai jos.
Nedefinit
Valoarea „nedefinită“ este atribuit tuturor variabilelor neinițializate , și este de asemenea returnat atunci când se verifică pentru proprietățile obiectelor care nu există. Într-un context boolean, valoarea nedefinită este considerată o valoare falsă.
Notă: nedefinit este considerat un tip primitiv autentic. Dacă nu este convertită în mod explicit, valoarea nedefinită se poate comporta în mod neașteptat în comparație cu alte tipuri care se evaluează la fals într-un context logic.
var test; // variable declared, but not defined, ...
// ... set to value of undefined
var testObj = {};
console.log(test); // test variable exists, but value not ...
// ... defined, displays undefined
console.log(testObj.myProp); // testObj exists, property does not, ...
// ... displays undefined
console.log(undefined == null); // unenforced type during check, displays true
console.log(undefined === null); // enforce type during check, displays false
Notă: Nu există un limbaj literal încorporat pentru nedefinit. Astfel, nu este un mod infailabil de a verifica dacă o variabilă este nedefinită, deoarece în versiunile anterioare ECMAScript 5, este legal ca cineva să scrie . O abordare mai robustă este de a compara folosind .
(x === undefined)var undefined = "I'm defined now";(typeof x === 'undefined')
Funcții de acest gen nu vor funcționa așa cum era de așteptat:
function isUndefined(x) { var u; return x === u; } // like this...
function isUndefined(x) { return x === void 0; } // ... or that second one
function isUndefined(x) { return (typeof x) === "undefined"; } // ... or that third one
Aici, apelarea isUndefined(my_var)generează un ReferenceError dacă my_var este un identificator necunoscut, în timp ce nu.
typeof my_var === 'undefined'
Număr
Numerele sunt reprezentate în binar ca IEEE-754 în virgulă dublă. Deși acest format oferă o precizie de aproape 16 cifre semnificative , nu poate reprezenta întotdeauna cu exactitate numere reale, inclusiv fracții.
Acest lucru devine o problemă la compararea sau formatarea numerelor. De exemplu:
console.log(0.2 + 0.1 === 0.3); // displays false
console.log(0.94 - 0.01); // displays 0.9299999999999999
Ca rezultat, ar trebui utilizată o rutină, cum ar fi metoda toFixed (), pentru a rotunji numerele ori de câte ori sunt formatate pentru ieșire .
Numerele pot fi specificate în oricare dintre aceste notații:
345; // an "integer", although there is only one numeric type in JavaScript
34.5; // a floating-point number
3.45e2; // another floating-point, equivalent to 345
0b1011; // a binary integer equal to 11
0o377; // an octal integer equal to 255
0xFF; // a hexadecimal integer equal to 255, digits represented by the ...
// ... letters A-F may be upper or lowercase
Există, de asemenea, un separator numeric, _ (sublinierea), introdus în ES2021:
// Note: Wikipedia syntax doesn't support numeric separators yet
1_000_000_000; // Used with big numbers
1_000_000.5; // Support with decimals
1_000e1_000; // Support with exponents
// Support with binary, octals and hex
0b0000_0000_0101_1011;
0o0001_3520_0237_1327;
0xFFFF_FFFF_FFFF_FFFE;
// But you can't use them next to a non-digit number part, or at the start or end
_12; // Variable is not defined (the underscore makes it a variable identifier)
12_; // Syntax error (cannot be at the end of numbers)
12_.0; // Syntax error (doesn't make sense to put a separator next to the decimal point)
12._0; // Syntax error
12e_6; // Syntax error (next to "e", a non-digit. Doesn't make sense to put a separator at the start)
1000____0000; // Syntax error (next to "_", a non-digit. Only 1 separator at a time is allowed
Extensiile + ∞ , −∞ și NaN (nu un număr) ale tipului de număr pot fi obținute prin două expresii de program:
Infinity; // positive infinity (negative obtained with -Infinity for instance)
NaN; // The Not-A-Number value, also returned as a failure in ...
// ... string-to-number conversions
Infinitul și NaN sunt numere:
typeof Infinity; // returns "number"
typeof NaN; // returns "number"
Aceste trei valori speciale corespund și se comportă așa cum le descrie IEEE-754 .
Constructorul numeric (utilizat ca funcție) sau un + sau - unar poate fi utilizat pentru a efectua conversii numerice explicite:
var myString = "123.456";
var myNumber1 = Number(myString);
var myNumber2 = +myString;
Atunci când este utilizat ca constructor, se creează un obiect numeric de împachetare (deși este de puțin folos):
myNumericWrapper = new Number(123.456);
Cu toate acestea, NaN nu este egal cu el însuși:
const nan = NaN;
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(NaN !== NaN); // true
console.log(nan !== nan); // true
// You can use the isNaN methods to check for NaN
console.log(isNaN("converted to NaN")); // true
console.log(isNaN(NaN)); // true
console.log(Number.isNaN("not converted")); // false
console.log(Number.isNaN(NaN)); // true
BigInt
BigInts poate fi utilizat pentru numere întregi arbitrare mari . Mai ales numerele întregi mai mari de 2 53 - 1, care este cel mai mare număr pe care JavaScript îl poate reprezenta în mod fiabil cu primitiva Number și reprezentată de constanta Number.MAX_SAFE_INTEGER.
La divizarea BigInts, rezultatele sunt trunchiate .
Şir
Un șir în JavaScript este o secvență de caractere. În JavaScript, șirurile pot fi create direct (ca litere) plasând seria de caractere între ghilimele duble (") sau simple ('). Aceste șiruri trebuie scrise pe o singură linie, dar pot include caractere de linie nouă evadate (cum ar fi \ n). Standardul JavaScript permite caracterului backquote (`, cu accent grav sau backtick) să citeze șiruri literale multiliniu, dar acest lucru este acceptat numai pe anumite browsere începând din 2016: Firefox și Chrome, dar nu și Internet Explorer 11.
var greeting = "Hello, World!";
var anotherGreeting = 'Greetings, people of Earth.';
Caracterele individuale dintr-un șir pot fi accesate folosind metoda charAt (furnizată de String.prototype ). Acesta este modul preferat atunci când accesați caractere individuale într-un șir, deoarece funcționează și în browsere non-moderne:
var h = greeting.charAt(0);
În browserele moderne, caracterele individuale dintr-un șir pot fi accesate (ca șiruri cu un singur caracter) prin aceeași notație ca matrici:
var h = greeting[0];
Cu toate acestea, șirurile JavaScript sunt imuabile :
greeting[0] = "H"; // Fails.
Aplicarea operatorului de egalitate ("==") la două șiruri returnează adevărat, dacă șirurile au același conținut, ceea ce înseamnă: de aceeași lungime și conținând aceeași secvență de caractere (majuscule este semnificativ pentru alfabete). Prin urmare:
var x = "World";
var compare1 = ("Hello, " +x == "Hello, World"); // Here compare1 contains true.
var compare2 = ("Hello, " +x == "hello, World"); // Here compare2 contains ...
// ... false since the ...
// ... first characters ...
// ... of both operands ...
// ... are not of the same case.
Cotațiile de același tip nu pot fi imbricate decât dacă sunt evadate .
var x = '"Hello, World!" he said.'; // Just fine.
var x = ""Hello, World!" he said."; // Not good.
var x = "\"Hello, World!\" he said."; // Works by escaping " with \"
Constructorul String creează un obiect șir (un obiect care înfășoară un șir):
var greeting = new String("Hello, World!");
Aceste obiecte au o metodă valueOf care returnează șirul primitiv înfășurat în ele:
var s = new String("Hello !");
typeof s; // Is 'object'.
typeof s.valueOf(); // Is 'string'.
Egalitatea dintre două obiecte șir nu se comportă ca la primitivele șir:
var s1 = new String("Hello !");
var s2 = new String("Hello !");
s1 == s2; // Is false, because they are two distinct objects.
s1.valueOf() == s2.valueOf(); // Is true.
Boolean
JavaScript oferă un tip de date boolean cu litere adevărate și false . Typeof Operatorul returnează șirul „boolean“ pentru aceste tipuri de primitive . Atunci când sunt utilizate într-un context logic, 0 , -0 , nul , NaN , nedefinit și șirul gol ( "" ) se evaluează ca fiind fals datorită constrângerii automate de tip . Toate celelalte valori ( complementul listei anterioare) sunt evaluate ca fiind adevărate , inclusiv șirurile „0” , „fals” și orice obiect.
Conversie tip
Coerciția automată de tip de către operatorii de comparare a egalității ( ==și !=) poate fi evitată folosind operatorii de comparație verificată de tip ( ===și !==).
Când este necesară conversia de tip, JavaScript convertește operandi Boolean , Number , String sau Object după cum urmează:
- Număr și șir
- Șirul este convertit într-o valoare numerică. JavaScript încearcă să convertească șirul numeric literal într-o valoare de tip Număr. În primul rând, o valoare matematică este derivată din șirul numeric literal. Apoi, această valoare este rotunjită la cea mai apropiată valoare de tip Număr.
- Boolean
- Dacă unul dintre operanzi este boolean, operandul boolean este convertit la 1 dacă este adevărat sau la 0 dacă este fals .
- Obiect
- Dacă un obiect este comparat cu un număr sau un șir, JavaScript încearcă să returneze valoarea implicită pentru obiect. Un obiect este convertit într-o primitivă String sau Number, folosind metodele .valueOf () sau .toString () ale obiectului. Dacă acest lucru eșuează, se generează o eroare de execuție.
Douglas Crockford susține termenii „ adevărat ” și „ fals ” pentru a descrie modul în care se comportă valorile de diferite tipuri atunci când sunt evaluate într-un context logic, în special în ceea ce privește cazurile marginale. Operatorii logici binari au returnat o valoare booleană în primele versiuni de JavaScript, dar acum returnează unul dintre operanzi. Stânga-operand este returnat, dacă poate fi evaluat ca: fals , în cazul conjuncției : ( a && b), sau adevărat , în cazul disjuncției : ( a || b); în caz contrar, dreptul de operand este returnat. Coerciția automată de tip de către operatorii de comparație poate diferi pentru cazurile de operanzi mixte booleeni și compatibili cu numărul (inclusiv șiruri care pot fi evaluate ca număr sau obiecte care pot fi evaluate ca un astfel de șir), deoarece operandul boolean va fi comparat ca o valoare numerică. Acest lucru poate fi neașteptat. O expresie poate fi exprimată în mod explicit la o primitivă booleană prin dublarea operatorului de negare logică : ( !! ), folosind funcția Boolean () sau folosind operatorul condițional : ( c ? t : f).
// Automatic type coercion
console.log(true == 2 ); // false... true → 1 !== 2 ← 2
console.log(false == 2 ); // false... false → 0 !== 2 ← 2
console.log(true == 1 ); // true.... true → 1 === 1 ← 1
console.log(false == 0 ); // true.... false → 0 === 0 ← 0
console.log(true == "2"); // false... true → 1 !== 2 ← "2"
console.log(false == "2"); // false... false → 0 !== 2 ← "2"
console.log(true == "1"); // true.... true → 1 === 1 ← "1"
console.log(false == "0"); // true.... false → 0 === 0 ← "0"
console.log(false == "" ); // true.... false → 0 === 0 ← ""
console.log(false == NaN); // false... false → 0 !== NaN
console.log(NaN == NaN); // false...... NaN is not equivalent to anything, including NaN.
// Type checked comparison (no conversion of types and values)
console.log(true === 1); // false...... data types do not match
// Explicit type coercion
console.log(true === !!2); // true.... data types and values match
console.log(true === !!0); // false... data types match, but values differ
console.log( 1 ? true : false); // true.... only ±0 and NaN are "falsy" numbers
console.log("0" ? true : false); // true.... only the empty string is "falsy"
console.log(Boolean({})); // true.... all objects are "truthy"
Noul operator poate fi folosit pentru a crea un ambalaj de obiecte pentru o primitivă booleană. Cu toate acestea, operatorul typeof nu returnează boolean pentru ambalajul obiectului, ci returnează obiectul . Deoarece toate obiectele sunt evaluate ca fiind adevărate , trebuie folosită o metodă precum .valueOf () sau .toString () pentru a recupera valoarea împachetată. Pentru constrângerea explicită la tipul boolean, Mozilla recomandă ca funcția Boolean () (fără nou ) să fie utilizată în preferință obiectului boolean.
var b = new Boolean(false); // Object false {}
var t = Boolean(b); // Boolean true
var f = Boolean(b.valueOf()); // Boolean false
var n = new Boolean(b); // Not recommended
n = new Boolean(b.valueOf()); // Preferred
if (0 || -0 || "" || null || undefined || b.valueOf() || !new Boolean() || !t) {
console.log("Never this");
} else if ([] && {} && b && typeof b === "object" && b.toString() === "false") {
console.log("Always this");
}
Simbol
Nou în ECMAScript6. Un simbol este un identificator unic și imuabil.
Exemplu:
var x = Symbol(1);
var y = Symbol(1);
x === y; // => false
var symbolObject = {};
var normalObject = {};
// since x and y are unique,
// they can be used as unique keys in an object
symbolObject[x] = 1;
symbolObject[y] = 2;
symbolObject[x]; // => 1
symbolObject[y]; // => 2
// as compared to normal numeric keys
normalObject[1] = 1;
normalObject[1] = 2; // overrides the value of 1
normalObject[1]; // => 2
// changing the value of x does not change the key stored in the object
x = Symbol(3);
symbolObject[x]; // => undefined
// changing x back just creates another unique Symbol
x = Symbol(1);
symbolObject[x]; // => undefined
Există, de asemenea, simboluri bine cunoscute .
Una dintre ele este Symbol.iterator; dacă ceva implementează Symbol.iterator, este iterabil:
let x = [1, 2, 3, 4]; // x is an Array
x[Symbol.iterator] === Array.prototype[Symbol.iterator]; // and Arrays are iterable
const xIterator = x[Symbol.iterator](); // The [Symbol.iterator] function should provide an iterator for x
xIterator.next(); // { value: 1, done: false }
xIterator.next(); // { value: 2, done: false }
xIterator.next(); // { value: 3, done: false }
xIterator.next(); // { value: 4, done: false }
xIterator.next(); // { value: undefined, done: true }
xIterator.next(); // { value: undefined, done: true }
// for..of loops automatically iterate values
for (const value of x) {
console.log(value); // 1 2 3 4
}
// Sets are also iterable:
[Symbol.iterator] in Set.prototype; // true
for (const value of new Set(['apple', 'orange'])) {
console.log(value); // "apple" "orange"
}
Obiecte native
Limbajul JavaScript oferă o mână de obiecte native . Obiectele native JavaScript sunt considerate parte a specificației JavaScript. Fără a aduce atingere mediului JavaScript, acest set de obiecte ar trebui să fie întotdeauna disponibil.
Matrice
Un Array este un obiect JavaScript prototipat din constructorul Array conceput special pentru a stoca valori de date indexate de chei întregi. Matricele, spre deosebire de tipul obiectului de bază, sunt prototipate cu metode și proprietăți pentru a ajuta programatorul în sarcinile de rutină (de exemplu, join , slice și push ).
La fel ca în familia C , matricile folosesc o schemă de indexare bazată pe zero: o valoare care este inserată într-o matrice goală prin intermediul metodei push ocupă indexul 0 al matricei.
var myArray = []; // Point the variable myArray to a newly ...
// ... created, empty Array
myArray.push("hello World"); // Fill the next empty index, in this case 0
console.log(myArray[0]); // Equivalent to console.log("hello World");
Matricile au o proprietate de lungime care este garantată să fie întotdeauna mai mare decât cel mai mare indice întreg utilizat în matrice. Se actualizează automat, dacă se creează o proprietate cu un index și mai mare. Scrierea unui număr mai mic la proprietatea lungime va elimina indicii mai mari.
Elementele din matrice pot fi accesate folosind notația normală de acces la proprietatea obiectului:
myArray[1]; // the 2nd item in myArray
myArray["1"];
Cele două de mai sus sunt echivalente. Nu este posibil să utilizați nota „punct” sau șiruri cu reprezentări alternative ale numărului:
myArray.1; // syntax error
myArray["01"]; // not the same as myArray[1]
Declarația unui tablou poate utiliza fie un literal Array, fie constructorul Array :
let myArray;
// Array literals
myArray = [1, 2]; // length of 2
myArray = [1, 2,]; // same array - You can also have an extra comma at the end
// It's also possible to not fill in parts of the array
myArray = [0, 1, /* hole */, /* hole */, 4, 5]; // length of 6
myArray = [0, 1, /* hole */, /* hole */, 4, 5,]; // same array
myArray = [0, 1, /* hole */, /* hole */, 4, 5, /* hole */,]; // length of 7
// With the constructor
myArray = new Array(0, 1, 2, 3, 4, 5); // length of 6
myArray = new Array(365); // an empty array with length 365
Tablourile sunt implementate astfel încât numai elementele definite să folosească memoria; sunt „ matrici rare ”. Setarea și folosește spațiu doar pentru aceste două elemente, la fel ca orice alt obiect. Lungimea de matrice va fi în continuare raportate 58. Lungimea maximă a unei matrice este 4294967295 , care corespunde număr binar de 32 biți (11111111111111111111111111111111) 2 .
myArray[10] = 'someThing'myArray[57] = 'somethingOther'
Se poate folosi literal declarația de obiect pentru a crea obiecte care se comportă la fel ca matricele asociative în alte limbi:
dog = {color: "brown", size: "large"};
dog["color"]; // results in "brown"
dog.color; // also results in "brown"
Se pot utiliza literele de declarație obiect și matrice pentru a crea rapid matrici care sunt asociative, multidimensionale sau ambele. (Din punct de vedere tehnic, JavaScript nu acceptă tablouri multidimensionale, dar le putem imita cu tablouri de tablouri.)
cats = [{color: "brown", size: "large"},
{color: "black", size: "small"}];
cats[0]["size"]; // results in "large"
dogs = {rover: {color: "brown", size: "large"},
spot: {color: "black", size: "small"}};
dogs["spot"]["size"]; // results in "small"
dogs.rover.color; // results in "brown"
Data
Un obiect Date stochează un număr semnat de milisecunde cu zero reprezentând 1970-01-01 00:00:00 UT și un interval de ± 10 8 zile. Există mai multe moduri de a oferi argumente constructorului Date . Rețineți că lunile sunt bazate pe zero.
new Date(); // create a new Date instance representing the current time/date.
new Date(2010, 2, 1); // create a new Date instance representing 2010-Mar-01 00:00:00
new Date(2010, 2, 1, 14, 25, 30); // create a new Date instance representing 2010-Mar-01 14:25:30
new Date("2010-3-1 14:25:30"); // create a new Date instance from a String.
Sunt furnizate metode de extragere a câmpurilor, precum și un șir util pentru :
var d = new Date(2010, 2, 1, 14, 25, 30); // 2010-Mar-01 14:25:30;
// Displays '2010-3-1 14:25:30':
console.log(d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' '
+ d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds());
// Built-in toString returns something like 'Mon Mar 01 2010 14:25:30 GMT-0500 (EST)':
console.log(d);
Eroare
Mesajele de eroare personalizate pot fi create utilizând clasa Eroare :
throw new Error("Something went wrong.");
Acestea pot fi capturate prin try ... catch ... în cele din urmă blocuri așa cum este descris în secțiunea privind gestionarea excepțiilor .
Matematica
Obiectul Math conține diverse constante legate de matematică (de exemplu, π ) și funcții (de exemplu, cosinus). (Rețineți că obiectul Math nu are niciun constructor, spre deosebire de Array sau Date . Toate metodele sale sunt „statice”, adică metode „de clasă”.) Toate funcțiile trigonometrice folosesc unghiuri exprimate în radiani , nu în grade sau grade .
| Proprietate | Valoare returnată rotunjită la 5 cifre |
Descriere |
|---|---|---|
| Math.E | 2.7183 | e : Baza logaritmului natural |
| Math.LN2 | 0,69315 | Logaritm natural de 2 |
| Math.LN10 | 2.3026 | Logaritm natural de 10 |
| Math.LOG2E | 1,4427 | Logaritm la baza 2 a e |
| Math.LOG10E | 0,44329 | Logaritm la baza 10 a e |
| Math.PI | 3.14159 | π : circumferința / diametrul unui cerc |
| Math.SQRT1_2 | 0,70711 | Rădăcină pătrată de ½ |
| Math.SQRT2 | 1.4142 | Rădăcină pătrată de 2 |
| Exemplu | Valoare returnată rotunjită la 5 cifre |
Descriere |
|---|---|---|
| Math.abs (-2,3) | 2.3 | Valoare absolută |
| Math.acos (Math.SQRT1_2) | 0,78540 rad. = 45 ° | Arccosine |
| Math.asin (Math.SQRT1_2) | 0,78540 rad. = 45 ° | Arcsine |
| Math.atan (1) | 0,78540 rad. = 45 ° | Jumătate cerc arctangentă (- π / 2 până la + π / 2) |
| Math.atan2 (-3,7, -3,7) | -2,3562 rad. = -135 ° | Arctangenta cercului întreg (- π la + π ) |
| Math.ceil (1.1) | 2 | Plafon: rotunjiți până la cel mai mic întreg ≥ argument |
| Math.cos (Math.PI / 4) | 0,70711 | Cosinus |
| Math.exp (1) | 2.7183 | Funcției exponențiale : e ridicat la această putere |
| Math.floor (1.9) | 1 | Etaj: rotunjiți în jos la cel mai mare argument ≤ întreg |
| Math.log (Math.E) | 1 | Logaritm natural, baza e |
| Math.max (1, -2) | 1 | Maxim: (x> y)? X y |
| Math.min (1, -2) | -2 | Minim: (x <y)? X y |
| Math.pow (-3, 2) | 9 | Exponențierea (ridicată la puterea lui): Math.pow (x, y) dă x y |
| Math.random () | de exemplu, 0.17068 | Număr aleatoriu între 0 (inclusiv) și 1 (exclusiv) |
| Math.round (1.5) | 2 | Rotunjiți la cel mai apropiat număr întreg; jumătăți de fracții sunt rotunjite în sus (de exemplu, 1,5 runde la 2) |
| Math.sin (Math.PI / 4) | 0,70711 | Sinus |
| Math.sqrt (49) | 7 | Rădăcină pătrată |
| Math.tan (Math.PI / 4) | 1 | Tangentă |
Expresie uzuala
/expression/.test(string); // returns Boolean
"string".search(/expression/); // returns position Number
"string".replace(/expression/, replacement);
// Here are some examples
if (/Tom/.test("My name is Tom")) console.log("Hello Tom!");
console.log("My name is Tom".search(/Tom/)); // == 11 (letters before Tom)
console.log("My name is Tom".replace(/Tom/, "John")); // == "My name is John"
Clasele de personaje
// \d - digit
// \D - non digit
// \s - space
// \S - non space
// \w - word char
// \W - non word
// [ ] - one of
// [^] - one not of
// - - range
if (/\d/.test('0')) console.log('Digit');
if (/[0-9]/.test('6')) console.log('Digit');
if (/[13579]/.test('1')) console.log('Odd number');
if (/\S\S\s\S\S\S\S/.test('My name')) console.log('Format OK');
if (/\w\w\w/.test('Tom')) console.log('Hello Tom');
if (/[a-zA-Z]/.test('B')) console.log('Letter');
Potrivirea personajelor
// A...Z a...z 0...9 - alphanumeric
// \u0000...\uFFFF - Unicode hexadecimal
// \x00...\xFF - ASCII hexadecimal
// \t - tab
// \n - new line
// \r - CR
// . - any character
// | - OR
if (/T.m/.test('Tom')) console.log ('Hi Tom, Tam or Tim');
if (/A|B/.test("A")) console.log ('A or B');
Repetatoare
// ? - 0 or 1 match
// * - 0 or more
// + - 1 or more
// {n} - exactly n
// {n,} - n or more
// {0,n} - n or less
// {n,m} - range n to m
if (/ab?c/.test("ac")) console.log("OK"); // match: "ac", "abc"
if (/ab*c/.test("ac")) console.log("OK"); // match: "ac", "abc", "abbc", "abbbc" etc.
if (/ab+c/.test("abc")) console.log("OK"); // match: "abc", "abbc", "abbbc" etc.
if (/ab{3}c/.test("abbbc")) console.log("OK"); // match: "abbbc"
if (/ab{3,}c/.test("abbbc")) console.log("OK"); // match: "abbbc", "abbbbc", "abbbbbc" etc.
if (/ab{1,3}c/.test("abc")) console.log("OK"); // match: "abc", "abbc", "abbbc"
Ancore
// ^ - string starts with
// $ - string ends with
if (/^My/.test("My name is Tom")) console.log ("Hi!");
if (/Tom$/.test("My name is Tom")) console.log ("Hi Tom!");
Subexpresie
// ( ) - groups characters
if (/water(mark)?/.test("watermark")) console.log("Here is water!"); // match: "water", "watermark",
if (/(Tom)|(John)/.test("John")) console.log("Hi Tom or John!");
Steaguri
// /g - global
// /i - ignore upper/lower case
// /m - allow matches to span multiple lines
console.log("hi tom!".replace(/Tom/i, "John")); // == "hi John!"
console.log("ratatam".replace(/ta/, "tu")); // == "ratutam"
console.log("ratatam".replace(/ta/g, "tu")); // == "ratutum"
Metode avansate
my_array = my_string.split(my_delimiter);
// example
my_array = "dog,cat,cow".split(","); // my_array==["dog","cat","cow"];
my_array = my_string.match(my_expression);
// example
my_array = "We start at 11:30, 12:15 and 16:45".match(/\d\d:\d\d/g); // my_array==["11:30","12:15","16:45"];
Captarea grupurilor
var myRe = /(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/;
var results = myRe.exec("The date and time are 2009-09-08 09:37:08.");
if (results) {
console.log("Matched: " + results[0]); // Entire match
var my_date = results[1]; // First group == "2009-09-08"
var my_time = results[2]; // Second group == "09:37:08"
console.log("It is " + my_time + " on " + my_date);
} else console.log("Did not find a valid date!");
Funcţie
Fiecare funcție din JavaScript este o instanță a constructorului de funcții :
// x, y is the argument. 'return x + y' is the function body, which is the last in the argument list.
var add = new Function('x', 'y', 'return x + y');
add(1, 2); // => 3
Funcția de adăugare de mai sus poate fi de asemenea definită folosind o expresie de funcție:
var add = function(x, y) {
return x + y;
};
add(1, 2); // => 3
În ES6, a fost adăugată sintaxa funcției săgeată, permițând funcțiilor care returnează o valoare să fie mai concise. De asemenea, păstrează acest obiect global în loc să-l moștenească de unde a fost numit / la ce a fost apelat, spre deosebire de expresia funcției () {} .
var add = (x, y) => {return x + y;};
// values can also be implicitly returned (i.e. no return statement is needed)
var addImplicit = (x, y) => x + y;
add(1, 2); // => 3
addImplicit(1, 2) // => 3
Pentru funcțiile care trebuie ridicate, există o expresie separată:
function add(x, y) {
return x + y;
}
add(1, 2); // => 3
Ridicarea vă permite să utilizați funcția înainte ca aceasta să fie „declarată”:
add(1, 2); // => 3, not a ReferenceError
function add(x, y) {
return x + y;
}
O instanță de funcție are proprietăți și metode.
function subtract(x, y) {
return x - y;
}
console.log(subtract.length); // => 2, arity of the function (number of arguments)
console.log(subtract.toString());
/*
"function subtract(x, y) {
return x - y;
}"
*/
Operatori
Operatorul '+' este suprasolicitat : este utilizat pentru concatenarea șirurilor și adăugarea aritmetică. Acest lucru poate cauza probleme atunci când amestecați involuntar șiruri și numere. Ca operator unar, poate converti un șir numeric într-un număr.
// Concatenate 2 strings
console.log('He' + 'llo'); // displays Hello
// Add two numbers
console.log(2 + 6); // displays 8
// Adding a number and a string results in concatenation (from left to right)
console.log(2 + '2'); // displays 22
console.log('$' + 3 + 4); // displays $34, but $7 may have been expected
console.log('$' + (3 + 4)); // displays $7
console.log(3 + 4 + '7'); // displays 77, numbers stay numbers until a string is added
// Convert a string to a number using the unary plus
console.log(+'2' === 2); // displays true
console.log(+'Hello'); // displays NaN
În mod similar, operatorul „*” este suprasolicitat: poate converti un șir într-un număr.
console.log(2 + '6'*1); // displays 8
console.log(3*'7'); // 21
console.log('3'*'7'); // 21
console.log('hello'*'world'); // displays NaN
Aritmetic
JavaScript acceptă următorii operatori aritmetici binari :
| + | plus |
| - | scădere |
| * | multiplicare |
| / | divizare (returnează o valoare în virgulă mobilă) |
| % | modulo (returnează restul) |
| ** | exponențierea |
JavaScript acceptă următorii operatori aritmetici unari :
| + | conversia unitară a șirului în număr |
| - | negatie unara (inverseaza semnul) |
| ++ | increment (poate fi prefix sau postfix) |
| - | decrement (poate fi prefix sau postfix) |
var x = 1;
console.log(++x); // x becomes 2; displays 2
console.log(x++); // displays 2; x becomes 3
console.log(x); // x is 3; displays 3
console.log(x--); // displays 3; x becomes 2
console.log(x); // displays 2; x is 2
console.log(--x); // x becomes 1; displays 1
Operatorul modulo afișează restul după împărțire la modul. Dacă sunt implicate numere negative, valoarea returnată depinde de operand.
var x = 17;
console.log(x%5); // displays 2
console.log(x%6); // displays 5
console.log(-x%5); // displays -2
console.log(-x%-5); // displays -2
console.log(x%-5); // displays 2
Pentru a returna întotdeauna un număr non-negativ, adăugați din nou modulul și aplicați din nou operatorul modulo:
var x = 17;
console.log((-x%5+5)%5); // displays 3
Misiune
| = | atribui |
| + = | adăugați și atribuiți |
| - = | scade și atribui |
| * = | înmulțiți și atribuiți |
| / = | împarte și atribuie |
| % = | modulo și assign |
| ** = | exponențierea și atribuirea |
Atribuirea de tipuri primitive
var x = 9;
x += 1;
console.log(x); // displays: 10
x *= 30;
console.log(x); // displays: 300
x /= 6;
console.log(x); // displays: 50
x -= 3;
console.log(x); // displays: 47
x %= 7;
console.log(x); // displays: 5
Atribuirea tipurilor de obiecte
/**
* To learn JavaScript objects...
*/
var object_1 = {a: 1}; // assign reference of newly created object to object_1
var object_2 = {a: 0};
var object_3 = object_2; // object_3 references the same object as object_2 does
object_3.a = 2;
message(); // displays 1 2 2
object_2 = object_1; // object_2 now references the same object as object_1
// object_3 still references what object_2 referenced before
message(); // displays 1 1 2
object_2.a = 7; // modifies object_1
message(); // displays 7 7 2
object_3.a = 5; // object_3 doesn't change object_2
message(); // displays 7 7 5
object_3 = object_2;
object_3.a=4; // object_3 changes object_1 and object_2
message(); // displays 4 4 4
/**
* Prints the console.log message
*/
function message() {
console.log(object_1.a + " " + object_2.a + " " + object_3.a);
}
Alocarea destructurării
În JavaScript Mozilla, de la versiunea 1.7, alocarea destructurării permite alocarea unor părți ale structurilor de date la mai multe variabile simultan. Partea stângă a unei atribuiri este un model care seamănă cu un obiect / matricea cuibărit în mod arbitrar care conține l-lvalues la frunzele sale care urmează să primească substructurile valorii atribuite.
var a, b, c, d, e;
[a, b, c] = [3, 4, 5];
console.log(a + ',' + b + ',' + c); // displays: 3,4,5
e = {foo: 5, bar: 6, baz: ['Baz', 'Content']};
var arr = [];
({baz: [arr[0], arr[3]], foo: a, bar: b}) = e;
console.log(a + ',' + b + ',' + arr); // displays: 5,6,Baz,,,Content
[a, b] = [b, a]; // swap contents of a and b
console.log(a + ',' + b); // displays: 6,5
[a, b, c] = [3, 4, 5]; // permutations
[a, b, c] = [b, c, a];
console.log(a + ',' + b + ',' + c); // displays: 4,5,3
Operator de împrăștiere / repaus
Standardul ECMAScript 2015 introduce operatorul „ ... ”, pentru conceptele conexe de „sintaxă spread” și „parametri de repaus”
Sintaxa Spread oferă un alt mod de a distruge matricele. Acesta indică faptul că elementele dintr-o matrice specificată trebuie utilizate ca parametri într-un apel de funcție sau ca elemente dintr-o matrice literală.
Cu alte cuvinte, „ ... ” transformă „ [... foo] ” în „ [foo [0], foo [1], foo [2]] ” și „ this.bar (... foo); "în" this.bar (foo [0], foo [1], foo [2]); ".
var a = [1, 2, 3, 4];
// It can be used multiple times in the same expression
var b = [...a, ...a]; // b = [1, 2, 3, 4, 1, 2, 3, 4];
// It can be combined with non-spread items.
var c = [5, 6, ...a, 7, 9]; // c = [5, 6, 1, 2, 3, 4, 7, 9];
// For comparison, doing this without the spread operator
// creates a nested array.
var d = [a, a]; // d = [[1, 2, 3, 4], [1, 2, 3, 4]]
// It works the same with function calls
function foo(arg1, arg2, arg3) {
console.log(arg1 + ':' + arg2 + ':' + arg3);
}
// You can use it even if it passes more parameters than the function will use
foo(...a); // "1:2:3" → foo(a[0], a[1], a[2], a[3]);
// You can mix it with non-spread parameters
foo(5, ...a, 6); // "5:1:2" → foo(5, a[0], a[1], a[2], a[3], 6);
// For comparison, doing this without the spread operator
// assigns the array to arg1, and nothing to the other parameters.
foo(a); // "1,2,3,4:undefined:undefined"
Când ... este utilizat într-o declarație de funcție , acesta indică un parametru de repaus . Parametrul rest trebuie să fie ultimul parametru numit în lista de parametri a funcției. I se va atribui o matrice care conține orice argumente transmise funcției care depășesc ceilalți parametri numiți. Cu alte cuvinte, primește „restul” argumentelor transmise funcției (de unde și numele).
function foo(a, b, ...c) {
console.log(c.length);
}
foo(1, 2, 3, 4, 5); // "3" → c = [3, 4, 5]
foo('a', 'b'); // "0" → c = []
Parametrii de repaus sunt similari cu obiectul argumentelor Javascript , care este un obiect asemănător matricei care conține toți parametrii (numiți și fără nume) în apelul de funcție curent. Spre deosebire de argumente , totuși, parametrii de odihnă sunt adevărate obiecte Array , astfel încât metode precum .slice () și .sort () pot fi utilizate direct pe ele.
... Operatorul poate fi utilizat numai cu matrice de obiecte. (Cu toate acestea, există o propunere de extindere a acestuia la Object s într-un viitor standard ECMAScript.)
Comparaţie
| == | egal |
| ! = | nu este egal |
| > | mai mare ca |
| > = | mai mare sau egal cu |
| < | mai puțin decât |
| <= | mai mic sau egal cu |
| === | identic (egal și de același tip) |
| ! == | nu identice |
Variabilele care fac referire la obiecte sunt egale sau identice numai dacă fac referire la același obiect:
var obj1 = {a: 1};
var obj2 = {a: 1};
var obj3 = obj1;
console.log(obj1 == obj2); //false
console.log(obj3 == obj1); //true
console.log(obj3 === obj1); //true
Vezi și String .
Logic
JavaScript oferă patru operatori logici:
- unar negație ( NU =! a )
- disjuncție binară ( OR = a || b ) și conjuncție ( AND = a && b )
- condițional ternar ( c? t: f )
În contextul unei operații logice, orice expresie se evaluează ca fiind adevărată, cu excepția următoarelor :
- Corzi: "" , '' ,
- Numere: 0 , -0 , NaN ,
- Special: nul , nedefinit ,
- Boolean: fals .
Funcția booleană poate fi utilizată pentru a converti în mod explicit la o primitivă de tip boolean :
// Only empty strings return false
console.log(Boolean("") === false);
console.log(Boolean("false") === true);
console.log(Boolean("0") === true);
// Only zero and NaN return false
console.log(Boolean(NaN) === false);
console.log(Boolean(0) === false);
console.log(Boolean(-0) === false); // equivalent to -1*0
console.log(Boolean(-2) === true);
// All objects return true
console.log(Boolean(this) === true);
console.log(Boolean({}) === true);
console.log(Boolean([]) === true);
// These types return false
console.log(Boolean(null) === false);
console.log(Boolean(undefined) === false); // equivalent to Boolean()
Operatorul NOT își evaluează operandul ca fiind boolean și returnează negația. Folosind operatorul de două ori la rând, ca negativ dublu , convertește în mod explicit o expresie într-o primitivă de tip boolean:
console.log( !0 === Boolean(!0));
console.log(Boolean(!0) === !!1);
console.log(!!1 === Boolean(1));
console.log(!!0 === Boolean(0));
console.log(Boolean(0) === !1);
console.log(!1 === Boolean(!1));
console.log(!"" === Boolean(!""));
console.log(Boolean(!"") === !!"s");
console.log(!!"s" === Boolean("s"));
console.log(!!"" === Boolean(""));
console.log(Boolean("") === !"s");
console.log(!"s" === Boolean(!"s"));
Operatorul ternar poate fi, de asemenea, utilizat pentru conversie explicită:
console.log([] == false); console.log([] ? true : false); // “truthy”, but the comparison uses [].toString()
console.log([0] == false); console.log([0]? true : false); // [0].toString() == "0"
console.log("0" == false); console.log("0"? true : false); // "0" → 0 ... (0 == 0) ... 0 ← false
console.log([1] == true); console.log([1]? true : false); // [1].toString() == "1"
console.log("1" == true); console.log("1"? true : false); // "1" → 1 ... (1 == 1) ... 1 ← true
console.log([2] != true); console.log([2]? true : false); // [2].toString() == "2"
console.log("2" != true); console.log("2"? true : false); // "2" → 2 ... (2 != 1) ... 1 ← true
Expresiile care utilizează funcții precum postincrementare ( i ++ ) au un efect secundar anticipat . JavaScript oferă evaluarea pe scurtcircuit a expresiilor; operandul din dreapta este executat numai dacă operandul din stânga nu este suficient pentru a determina valoarea expresiei.
console.log(a || b); // When a is true, there is no reason to evaluate b.
console.log(a && b); // When a is false, there is no reason to evaluate b.
console.log(c ? t : f); // When c is true, there is no reason to evaluate f.
În primele versiuni ale JavaScript și JScript , operatorii logici binari au returnat o valoare booleană (la fel ca majoritatea limbajelor de programare derivate din C). Cu toate acestea, toate implementările contemporane returnează unul dintre operanzii lor în schimb:
console.log(a || b); // if a is true, return a, otherwise return b
console.log(a && b); // if a is false, return a, otherwise return b
Programatorii care sunt mai familiarizați cu comportamentul din C ar putea găsi această caracteristică surprinzătoare, dar permite o exprimare mai concisă a tiparelor, cum ar fi coalescența nulă :
var s = t || "(default)"; // assigns t, or the default value, if t is null, empty, etc.
Alocare logică
| ?? = | Sarcină nulă |
| || = | Logică sau atribuire |
| && = | Logică și atribuire |
Bitwise
JavaScript acceptă următorii operatori binari bit :
| & | ȘI |
| | | SAU |
| ^ | XOR |
| ! | NU |
| << | deplasare la stânga (umplere zero la dreapta) |
| >> | deplasați la dreapta (propagarea semnelor); copii ale bitului din stânga (bitul de semn) sunt deplasate din stânga |
| >>> | deplasați la dreapta (umplere zero la stânga). Pentru numere pozitive, >> și >>> dau același rezultat. |
Exemple:
x=11 & 6;
console.log(x); // 2
JavaScript acceptă următorul operator unitar pe biți :
| ~ | NU (inversează biții) |
Atribuire bitwise
JavaScript acceptă următorii operatori de atribuire binară:
| & = | și |
| | = | sau |
| ^ = | xor |
| << = | deplasare la stânga (umplere zero la dreapta) |
| >> = | deplasați la dreapta (propagarea semnelor); copii ale bitului din stânga (bitul de semn) sunt deplasate din stânga |
| >>> = | deplasați la dreapta (umplere zero la stânga). Pentru numerele pozitive, >> = și >>> = dau același rezultat. |
Exemple:
x=7;
console.log(x); // 7
x<<=3;
console.log(x); // 7->14->28->56
Şir
| = | misiune |
| + | concatenare |
| + = | concatenează și atribuie |
Exemple:
str = "ab" + "cd"; // "abcd"
str += "e"; // "abcde"
str2 = "2" + 2; // "22", not "4" or 4.
??
Cel mai apropiat operator JavaScript este ??, „operatorul nullish coalescing”, care a fost adăugat standardului în cea de-a XI-a ediție a ECMAScript . În versiunile anterioare, ar putea fi utilizat printr-un plugin Babel și în TypeScript . Acesta își evaluează operandul din stânga și, dacă valoarea rezultatului nu este „nulă” ( nullsau undefined), ia acea valoare ca rezultat; în caz contrar, evaluează operandul din dreapta și ia ca rezultat valoarea rezultată.
În exemplul următor, ava fi atribuită valoarea bdacă valoarea lui bnu este nullsau undefined, altfel va fi atribuită 3.
const a = b ?? 3;
Înainte de operatorul de coaliție nul, programatorii ar folosi operatorul OR logic ( ||). Dar , în cazul în care ??caută în mod specific nullsau undefined, de ||aspectul operator pentru orice falsy valoare: null, undefined, "", 0, NaN, și, desigur, false.
În exemplul următor, i se ava atribui valoarea bdacă valoarea lui beste adevărată , altfel i se va atribui 3.
const a = b || 3;
Structuri de control
Enunțuri compuse
O pereche de paranteze cretate {} și o secvență închisă de instrucțiuni constituie o instrucțiune compusă, care poate fi utilizată oriunde poate fi utilizată o instrucțiune.
Dacă ... altfel
if (expr) {
//statements;
} else if (expr2) {
//statements;
} else {
//statements;
}
Operator condiționat (ternar)
Operatorul condițional creează o expresie care se evaluează ca una dintre cele două expresii în funcție de o condiție. Acest lucru este similar cu instrucțiunea if care selectează una dintre cele două instrucțiuni de executat în funcție de o condiție. Adică, operatorul condiționat este la expresii, dacă este la instrucțiuni.
result = condition ? expression : alternative;
este la fel ca:
if (condition) {
result = expression;
} else {
result = alternative;
}
Spre deosebire de instrucțiunea if , operatorul condiționat nu poate omite „else-branch”.
Declarație de comutare
Sintaxa declarației de comutare JavaScript este următoarea:
switch (expr) {
case SOMEVALUE:
// statements;
break;
case ANOTHERVALUE:
// statements;
break;
default:
// statements;
break;
}
- pauză; este opțional; cu toate acestea, este de obicei necesar, deoarece altfel executarea codului va continua până la corpul următorului bloc de cazuri.
- Adăugați o declarație de pauză la sfârșitul ultimului caz ca măsură de precauție, în cazul în care se adaugă cazuri suplimentare ulterior.
- Șirul valorilor literal poate fi, de asemenea, utilizat pentru valorile de caz.
- Expresiile pot fi folosite în locul valorilor.
- Cazul implicit (opțional) se execută atunci când expresia nu se potrivește cu niciun alt caz specificat.
- Sunt necesare aparate dentare.
Pentru buclă
Sintaxa buclei JavaScript pentru este următoarea:
for (initial; condition; loop statement) {
/*
statements will be executed every time
the for{} loop cycles, while the
condition is satisfied
*/
}
sau
for (initial; condition; loop statement(iteration)) // one statement
Pentru ... în buclă
Sintaxa JavaScript for ... in loopeste următoarea:
for (var property_name in some_object) {
// statements using some_object[property_name];
}
- Iterează toate proprietățile enumerabile ale unui obiect.
- Iterează prin toți indicii de matrice folosiți, inclusiv toate proprietățile definite de utilizator ale obiectului matricei, dacă există. Astfel, ar putea fi mai bine să utilizați o buclă tradițională cu un index numeric atunci când iterați peste matrice.
- Există diferențe între diferitele browsere Web în ceea ce privește proprietățile care vor fi reflectate cu instrucțiunea for ... in loop. În teorie, aceasta este controlată de o proprietate de stare internă definită de standardul ECMAscript numit „DontEnum”, dar în practică, fiecare browser returnează un set ușor diferit de proprietăți în timpul introspecției. Este util să testați o anumită proprietate folosind }. Astfel, adăugarea unei metode la prototipul matricei cu } poate face bucle să se bucle peste numele metodei.
if (some_object.hasOwnProperty(property_name)) { ...Array.prototype.newMethod = function() {...for ... in
În timp ce bucla
Sintaxa buclei JavaScript while este următoarea:
while (condition) {
statement1;
statement2;
statement3;
...
}
Faceți ... în buclă
Sintaxa JavaScript do ... while loopeste următoarea:
do {
statement1;
statement2;
statement3;
...
} while (condition);
Cu
Instrucțiunea cu adaugă toate proprietățile și metodele obiectului dat în domeniul de aplicare al următorului bloc, permițându-le să fie menționate ca și cum ar fi variabile locale.
with (document) {
var a = getElementById('a');
var b = getElementById('b');
var c = getElementById('c');
};
- Rețineți absența documentului. înainte de fiecare invocație getElementById () .
Semantica este similară cu afirmația lui Pascal .
Deoarece disponibilitatea cu instrucțiuni împiedică performanța programului și se crede că reduce claritatea codului (deoarece orice variabilă dată ar putea fi de fapt o proprietate dintr-o anexare cu ), această instrucțiune nu este permisă în mod strict .
Etichete
JavaScript acceptă etichete imbricate în majoritatea implementărilor. Buclele sau blocurile pot fi etichetate pentru instrucțiunea break și buclele pentru continuare . Deși goto este un cuvânt rezervat, goto nu este implementat în JavaScript.
loop1: for (var a = 0; a < 10; a++) {
if (a == 4) {
break loop1; // Stops after the 4th attempt
}
console.log('a = ' + a);
loop2: for (var b = 0; b < 10; ++b) {
if (b == 3) {
continue loop2; // Number 3 is skipped
}
if (b == 6) {
continue loop1; // Continues the first loop, 'finished' is not shown
}
console.log('b = ' + b);
}
console.log('finished');
}
block1: {
console.log('Hello'); // Displays 'Hello'
break block1;
console.log('World'); // Will never get here
}
goto block1; // Parse error.
Funcții
O funcție este un bloc cu o listă de parametri (posibil goală) căreia îi este dat în mod normal un nume. O funcție poate utiliza variabile locale. Dacă ieșiți din funcție fără o instrucțiune return, se returnează valoarea nedefinită .
function gcd(segmentA, segmentB) {
var diff = segmentA - segmentB;
if (diff == 0)
return segmentA;
return diff > 0 ? gcd(segmentB, diff) : gcd(segmentA, -diff);
}
console.log(gcd(60, 40)); // 20
var mygcd = gcd; // mygcd is a reference to the same function as gcd. Note no argument ()s.
console.log(mygcd(60, 40)); // 20
Funcțiile sunt obiecte de primă clasă și pot fi atribuite altor variabile.
Numărul de argumente date la apelarea unei funcții poate să nu corespundă în mod necesar cu numărul de argumente din definiția funcției; un argument numit în definiție care nu are un argument de potrivire în apel va avea valoarea nedefinită (care poate fi implicit transformată în falsă). În cadrul funcției, argumentele pot fi accesate și prin intermediul obiectului argumente ; aceasta oferă acces la toate argumentele folosind indici (de exemplu ), inclusiv la cele care depășesc numărul de argumente numite. ( În timp ce lista argumente are un .length de proprietate, este nu o instanță de matrice , ea nu are metode cum ar fi .slice () , .sort () , etc.)
arguments[0], arguments[1], ... arguments[n]
function add7(x, y) {
if (!y) {
y = 7;
}
console.log(x + y + arguments.length);
};
add7(3); // 11
add7(3, 4); // 9
Valorile primitive (număr, boolean, șir) sunt trecute de valoare. Pentru obiecte, este trimiterea la obiect.
var obj1 = {a : 1};
var obj2 = {b : 2};
function foo(p) {
p = obj2; // Ignores actual parameter
p.b = arguments[1];
}
foo(obj1, 3); // Does not affect obj1 at all. 3 is additional parameter
console.log(obj1.a + " " + obj2.b); // writes 1 3
Funcțiile pot fi declarate în interiorul altor funcții și pot accesa variabilele locale ale funcției externe. În plus, implementează închideri complete, reținând variabilele locale ale funcției externe chiar și după ce funcția exterioară a ieșit.
var v = "Top";
var bar, baz;
function foo() {
var v = "fud";
bar = function() { console.log(v) };
baz = function(x) { v = x; };
}
foo();
baz("Fugly");
bar(); // Fugly (not fud) even though foo() has exited.
console.log(v); // Top
Asincronizează / așteaptă
Operatorul de așteptare din JavaScript poate fi utilizat numai din interiorul unei funcții asincronizate. Dacă parametrul este o promisiune , executarea funcției de asincronizare va fi reluată atunci când promisiunea este rezolvată (cu excepția cazului în care promisiunea este respinsă, caz în care va fi aruncată o eroare care poate fi tratată cu gestionarea normală a excepțiilor JavaScript ). Dacă parametrul nu este o promisiune, parametrul în sine va fi returnat imediat.
Multe biblioteci oferă obiecte promițătoare care pot fi folosite și cu wait, atâta timp cât se potrivesc cu specificațiile pentru promisiunile JavaScript native. Cu toate acestea, promisiunile din biblioteca jQuery nu erau compatibile cu Promisiunile / A + până la jQuery 3.0.
Iată un exemplu (modificat din acest articol):
async function createNewDoc() {
let response = await db.post({}); // post a new doc
return await db.get(response.id); // find by id
}
async function main() {
try {
let doc = await createNewDoc();
console.log(doc);
} catch (err) {
console.log(err);
}
}
main();
Obiecte
Pentru comoditate, tipurile sunt în mod normal împărțite în primitive și obiecte . Obiectele sunt entități care au o identitate (sunt egale doar cu ele însele) și care mapează numele proprietăților la valori („sloturi” în terminologia de programare bazată pe prototip ). Obiectele pot fi considerate ca tablouri sau hash-uri asociative și sunt adesea implementate folosind aceste structuri de date. Cu toate acestea, obiectele au caracteristici suplimentare, cum ar fi un lanț prototip, pe care matricele asociative obișnuite nu le au.
JavaScript are mai multe tipuri de obiecte încorporate, și anume Array , Boolean , Date , Function , Math , Number , Object , RegExp și String . Alte obiecte sunt „obiecte gazdă”, definite nu de limbă, ci de mediul de rulare. De exemplu, într-un browser, obiectele gazdă tipice aparțin DOM (fereastră, formular, linkuri etc.).
Crearea obiectelor
Obiectele pot fi create folosind un constructor sau un obiect literal. Constructorul poate folosi fie o funcție Object încorporată, fie o funcție personalizată. Este o convenție că funcțiile constructorului primesc un nume care începe cu o literă mare:
// Constructor
var anObject = new Object();
// Object literal
var objectA = {};
var objectA2 = {}; // A != A2, {}s create new objects as copies.
var objectB = {index1: 'value 1', index2: 'value 2'};
// Custom constructor (see below)
Literalele obiectelor și literele matrice permit crearea cu ușurință a structurilor de date flexibile:
var myStructure = {
name: {
first: "Mel",
last: "Smith"
},
age: 33,
hobbies: ["chess", "jogging"]
};
Aceasta este baza pentru JSON , care este o notație simplă care folosește sintaxă asemănătoare JavaScript pentru schimbul de date.
Metode
O metodă este pur și simplu o funcție care a fost atribuită unui nume de proprietate al unui obiect. Spre deosebire de multe limbaje orientate pe obiecte, nu există nicio distincție între o definiție a funcției și o definiție a metodei în JavaScript legat de obiect. Mai degrabă, distincția are loc în timpul apelului funcțional; o funcție poate fi numită ca metodă.
Când este apelat ca metodă, variabila locală standard , acest lucru este doar setat automat la instanta de obiect la stânga „ “. (Există, de asemenea, metode de apelare și aplicare care pot seta acest lucru în mod explicit - unele pachete precum jQuery fac lucruri neobișnuite cu acest lucru .)
În exemplul de mai jos, Foo este folosit ca constructor. Nu există nimic special la un constructor - este doar o funcție simplă care inițializează un obiect. Când este utilizat cu noul cuvânt cheie, așa cum este normal, acesta este setat la un obiect gol nou creat.
Rețineți că în exemplul de mai jos, Foo pur și simplu atribuie valori sloturilor, dintre care unele sunt funcții. Astfel, poate atribui funcții diferite instanțelor diferite. Nu există prototipuri în acest exemplu.
function px() { return this.prefix + "X"; }
function Foo(yz) {
this.prefix = "a-";
if (yz > 0) {
this.pyz = function() { return this.prefix + "Y"; };
} else {
this.pyz = function() { return this.prefix + "Z"; };
}
this.m1 = px;
return this;
}
var foo1 = new Foo(1);
var foo2 = new Foo(0);
foo2.prefix = "b-";
console.log("foo1/2 " + foo1.pyz() + foo2.pyz());
// foo1/2 a-Y b-Z
foo1.m3 = px; // Assigns the function itself, not its evaluated result, i.e. not px()
var baz = {"prefix": "c-"};
baz.m4 = px; // No need for a constructor to make an object.
console.log("m1/m3/m4 " + foo1.m1() + foo1.m3() + baz.m4());
// m1/m3/m4 a-X a-X c-X
foo1.m2(); // Throws an exception, because foo1.m2 doesn't exist.
Constructori
Funcțiile constructor atribuie pur și simplu valori sloturilor unui obiect nou creat. Valorile pot fi date sau alte funcții.
Exemplu: manipularea unui obiect:
function MyObject(attributeA, attributeB) {
this.attributeA = attributeA;
this.attributeB = attributeB;
}
MyObject.staticC = "blue"; // On MyObject Function, not object
console.log(MyObject.staticC); // blue
object = new MyObject('red', 1000);
console.log(object.attributeA); // red
console.log(object["attributeB"]); // 1000
console.log(object.staticC); // undefined
object.attributeC = new Date(); // add a new property
delete object.attributeB; // remove a property of object
console.log(object.attributeB); // undefined
delete object; // remove the whole Object (rarely used)
console.log(object.attributeA); // throws an exception
Constructorul în sine este menționat în slotul de constructor al prototipului obiectului . Asa de,
function Foo() {}
// Use of 'new' sets prototype slots (for example,
// x = new Foo() would set x's prototype to Foo.prototype,
// and Foo.prototype has a constructor slot pointing back to Foo).
x = new Foo();
// The above is almost equivalent to
y = {};
y.constructor = Foo;
y.constructor();
// Except
x.constructor == y.constructor // true
x instanceof Foo // true
y instanceof Foo // false
// y's prototype is Object.prototype, not
// Foo.prototype, since it was initialised with
// {} instead of new Foo.
// Even though Foo is set to y's constructor slot,
// this is ignored by instanceof - only y's prototype's
// constructor slot is considered.
Funcțiile sunt obiecte în sine, care pot fi utilizate pentru a produce un efect similar cu „proprietățile statice” (folosind terminologia C ++ / Java) așa cum se arată mai jos. (Obiectul funcțional are, de asemenea, o proprietate prototip specială , așa cum este discutat în secțiunea „Moștenire” de mai jos.)
Ștergerea obiectelor este folosită rar, deoarece motorul de scriptare va colecta gunoiul obiectelor la care nu se mai face referire.
Moştenire
JavaScript acceptă ierarhiile de moștenire prin prototipare în maniera Sinelui .
În exemplul următor, clasa Derivată moștenește din clasa Bază . Când d este creat ca Derivat , referința la instanța de bază a bazei este copiată în d.base .
Derivarea nu conține o valoare pentru aBaseFunction , deci este recuperată de la aBaseFunction atunci când se accesează aBaseFunction . Acest lucru este clar prin schimbarea valorii funcției base.aBaseFunction , care se reflectă în valoarea d.aBaseFunction .
Unele implementări permit accesul sau setarea în mod explicit a prototipului folosind slotul __proto__ așa cum se arată mai jos.
function Base() {
this.anOverride = function() { console.log("Base::anOverride()"); };
this.aBaseFunction = function() { console.log("Base::aBaseFunction()"); };
}
function Derived() {
this.anOverride = function() { console.log("Derived::anOverride()"); };
}
base = new Base();
Derived.prototype = base; // Must be before new Derived()
Derived.prototype.constructor = Derived; // Required to make `instanceof` work
d = new Derived(); // Copies Derived.prototype to d instance's hidden prototype slot.
d instanceof Derived; // true
d instanceof Base; // true
base.aBaseFunction = function() { console.log("Base::aNEWBaseFunction()"); }
d.anOverride(); // Derived::anOverride()
d.aBaseFunction(); // Base::aNEWBaseFunction()
console.log(d.aBaseFunction == Derived.prototype.aBaseFunction); // true
console.log(d.__proto__ == base); // true in Mozilla-based implementations and false in many others.
Următorul arată clar modul în care referințele la prototipuri sunt copiate la crearea instanțelor, dar modificările aduse unui prototip pot afecta toate instanțele care se referă la acesta.
function m1() { return "One"; }
function m2() { return "Two"; }
function m3() { return "Three"; }
function Base() {}
Base.prototype.m = m2;
bar = new Base();
console.log("bar.m " + bar.m()); // bar.m Two
function Top() { this.m = m3; }
t = new Top();
foo = new Base();
Base.prototype = t;
// No effect on foo, the *reference* to t is copied.
console.log("foo.m " + foo.m()); // foo.m Two
baz = new Base();
console.log("baz.m " + baz.m()); // baz.m Three
t.m = m1; // Does affect baz, and any other derived classes.
console.log("baz.m1 " + baz.m()); // baz.m1 One
În practică sunt folosite multe variante ale acestor teme și poate fi atât puternică, cât și confuză.
Manevrarea excepțiilor
JavaScript include o declarație de try ... catch ... finally gestionare a excepțiilor pentru a gestiona erorile în timpul rulării.
În try ... catch ... finallycapturile Declarație excepțiile care rezultă dintr - o eroare sau o declarație aruncare. Sintaxa sa este următoarea:
try {
// Statements in which exceptions might be thrown
} catch(errorValue) {
// Statements that execute in the event of an exception
} finally {
// Statements that execute afterward either way
}
Inițial, declarațiile din blocul try se execută. Dacă se aruncă o excepție, fluxul de control al scriptului se transferă imediat la instrucțiunile din blocul de captură, cu excepția disponibilă ca argument de eroare. În caz contrar, blocul de blocare este omis. Blocul de captură poate arunca (errorValue) , dacă nu dorește să gestioneze o eroare specifică.
În orice caz, declarațiile din blocul final sunt întotdeauna executate. Aceasta poate fi utilizată pentru a elibera resurse, deși memoria este colectată automat la gunoi.
Fie captura, fie clauza finală pot fi omise. Este necesar argumentul capturii.
Implementarea Mozilla permite mai multe declarații de captură, ca o extensie la standardul ECMAScript. Urmează o sintaxă similară cu cea utilizată în Java :
try { statement; }
catch (e if e == "InvalidNameException") { statement; }
catch (e if e == "InvalidIdException") { statement; }
catch (e if e == "InvalidEmailException") { statement; }
catch (e) { statement; }
Într-un browser, evenimentul onerror este mai frecvent utilizat pentru a prinde excepții.
onerror = function (errorValue, url, lineNr) {...; return true;};
Funcții și metode native
eval (expresie)
Evaluează primul parametru ca o expresie, care poate include instrucțiuni de atribuire. Variabilele locale la funcții pot fi menționate prin expresie. Cu toate acestea, evalreprezintă un risc major de securitate, deoarece permite unui actor rău să execute cod arbitrar, astfel încât utilizarea acestuia este descurajată.
(function foo() {
var x = 7;
console.log("val " + eval("x + 2"));
})(); // shows val 9.
Vezi si
Referințe
Lecturi suplimentare
- Danny Goodman: JavaScript Bible , Wiley, John & Sons, ISBN 0-7645-3342-8 .
- David Flanagan, Paula Ferguson: JavaScript: The Definitive Guide , O'Reilly & Associates, ISBN 0-596-10199-6 .
- Thomas A. Powell, Fritz Schneider: JavaScript: The Complete Reference , McGraw-Hill Companies, ISBN 0-07-219127-9 .
- Axel Rauschmayer: Speaking JavaScript: An In-Depth Guide for Programmers , 460 pages, O'Reilly Media, 25 February 2014, ISBN 978-1449365035 . ( ediție online gratuită )
- Emily Vander Veer: JavaScript For Dummies, ediția a IV-a , Wiley, ISBN 0-7645-7659-3 .
linkuri externe
- O reintroducere la JavaScript - Mozilla Developer Center
- Bucle JavaScript
- Referințe standard ECMAScript: ECMA-262
- Lecții interactive JavaScript - bazate pe exemple
- JavaScript pe About.com: lecții și explicații
- Formare JavaScript
- Referințele de bază ale Centrului pentru dezvoltatori Mozilla pentru versiunile JavaScript 1.5 , 1.4 , 1.3 și 1.2
- Documentație lingvistică Mozilla JavaScript