JavaScript -syntaks - JavaScript syntax

Den syntaks av Javascript er et sett med regler som definerer en riktig strukturert Javascript-program.

Eksemplene nedenfor bruker loggfunksjonen til konsollobjektet som finnes i de fleste nettlesere for standard tekstutskrift .

JavaScript -standardbiblioteket mangler en offisiell standard tekstutskriftsfunksjon (med unntak av document.write). Gitt at JavaScript hovedsakelig brukes til skripting på klientsiden i moderne nettlesere , og at nesten alle nettlesere gir varselfunksjonen, kan varsel også brukes, men er ikke vanlig.

Opprinnelse

Brendan Eich oppsummerte opprinnelsen til syntaksen i første ledd i JavaScript 1.1 -spesifikasjonen som følger:

JavaScript låner det meste av syntaksen fra Java , men arver også fra Awk og Perl , med en viss indirekte påvirkning fra Self i objektprototypesystemet .

Grunnleggende

Saksfølsomhet

JavaScript er skille mellom store og små bokstaver . Det er vanlig å starte navnet på en konstruktør med store bokstaver, og navnet på en funksjon eller variabel med en liten bokstav.

Eksempel:

var a=5;
console.log(a); // 5
console.log(A); // throws a ReferenceError: A is not defined

Mellomrom og semikolon

I motsetning til i C , kan mellomrom i JavaScript -kilden direkte påvirke semantikk . Semikolon avslutter setninger i JavaScript. På grunn av automatisk semikoloninnsetting (ASI), vil noen utsagn som er godt dannet når en ny linje blir analysert, betraktes som fullstendige, som om et semikolon ble satt inn like før nylinjen. Noen myndigheter anbefaler eksplisitt å levere semikolon som avslutter uttalelser, fordi det kan redusere utilsiktede effekter av automatisk semikoloninnsetting.

Det er to spørsmål: fem tokens kan enten starte en uttalelse eller være forlengelsen av en komplett setning; og fem begrensede produksjoner, der linjeskift ikke er tillatt i visse posisjoner, noe som potensielt gir feil analysering.

De fem problematiske symboler er startparentes " ( ", åpen jernet " [ ", skråstrek " / ", plus " + ", og minus " - " Av disse er den åpne parentes vanlig i. Rett-påkalte funksjon uttrykk mønster , og åpen brakett forekommer noen ganger, mens andre er ganske sjeldne. Eksemplet gitt i spesifikasjonen er:

a = b + c
(d + e).foo()

// Treated as:
//  a = b + c(d + e).foo();

med forslaget om at den foregående uttalelsen avsluttes med et semikolon.

Noen foreslår i stedet bruk av ledende semikolon på linjer som begynner med ' ( ' eller ' [ ', så linjen ikke tilfeldigvis blir forbundet med den forrige. Dette er kjent som et defensivt semikolon , og anbefales spesielt, fordi kode ellers kan bli tvetydig når det omorganiseres. For eksempel:

a = b + c
;(d + e).foo()

// Treated as:
//  a = b + c;
//  (d + e).foo();

Innledende semikolon brukes også noen ganger ved starten av JavaScript -biblioteker, i tilfelle de legges til et annet bibliotek som utelater et etterfølgende semikolon, da dette kan resultere i tvetydighet i den første setningen.

De fem begrensede produksjonene er retur , kast , pause , fortsett og etter-økning/reduksjon. I alle tilfeller løser ikke innsetting av semikolon problemet, men gjør den analyserte syntaksen klar, noe som gjør feilen lettere å oppdage. retur og kast ta en valgfri verdi, mens pause og fortsett å ta en valgfri etikett. I alle tilfeller er rådet å beholde verdien eller etiketten på samme linje som utsagnet. Dette viser oftest seg i returoppgaven, der man kan returnere et stort objekt bokstavelig talt, som ved et uhell kan plasseres fra en ny linje. For post-inkrement/decrement er det potensiell tvetydighet med pre-increment/decrement, og igjen anbefales det å bare holde disse på samme linje.

return
a + b;

// Returns undefined. Treated as:
//   return;
//   a + b;
// Should be written as:
//   return a + b;

Kommentarer

Kommentarsyntaks er den samme som i C ++ , Swift og mange andre språk.

// 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 */

Variabler

Variabler i standard JavaScript har ingen type tilknyttet, så enhver verdi (hver verdi har en type) kan lagres i en hvilken som helst variabel. Fra og med ES6 , den sjette versjon av språket, kan variablene bli erklært med varfor funksjonsomfang variabler, og leteller constsom er til blokknivå variabler. Før ES6 kunne variabler bare deklareres med en varuttalelse. Verdier som er tilordnet variabler deklarert med constkan ikke endres, men egenskapene kan. En variabels identifikator må starte med en bokstav, understreking ( _ ) eller dollartegn ( $ ), mens etterfølgende tegn også kan være sifre ( 0-9 ). JavaScript er store og små bokstaver, så store bokstaver "A" til "Z" er forskjellige fra små bokstaver "a" til "z".

Fra og med JavaScript 1.5 kan ISO 8859-1 eller Unicode- bokstaver (eller \ uXXXX Unicode escape-sekvenser) brukes i identifikatorer. I visse JavaScript -implementeringer kan at -tegnet (@) brukes i en identifikator, men dette er i strid med spesifikasjonene og støttes ikke i nyere implementeringer.

Omfang og heising

Variabler deklarert med varer leksikalt omfangs ved et funksjonsnivå , samtidig som de med leteller constha et blokknivå omfang. Erklæringer behandles før noen kode kjøres. Dette omtales som heising , og det tilsvarer at variabler blirdeklarert fremoverpå toppen av funksjonen eller blokken.

Med var, letog constuttalelser, heises bare erklæringen; oppgaver heises ikke. Således er en setning i midten av funksjonen ekvivalent med en erklæringserklæring øverst i funksjonen, og en tildelingserklæring på det tidspunktet i midten av funksjonen. Dette betyr at verdier ikke kan nås før de deklareres; fremoverreferanse er ikke mulig. Med en variabel er verdien til den initialiseres. Variabler som er deklarert med eller ikke kan nås før den er initialisert, så det vil føre til en feil å referere til variabelen. var x = 1var xx = 1varundefinedletconst

Funksjonserklæringer, som deklarerer en variabel og tilordner en funksjon til den, ligner variabeluttalelser, men i tillegg til å heise erklæringen, heiser de også oppgaven - som om hele setningen dukket opp øverst i funksjonen som inneholder - og dermed fremoverreferanse er også mulig: plasseringen av en funksjonserklæring i en omsluttende funksjon er irrelevant. Dette er forskjellig fra et funksjonsuttrykk blir tildelt til en variabel i en var, leteller constsetning.

Så, for eksempel,

var func = function() { .. } // declaration is hoisted only
function func() { .. } // declaration and assignment are hoisted

Blokkeringsomfang kan produseres ved å pakke hele blokken inn i en funksjon og deretter utføre den-dette er kjent som det umiddelbart påkalte funksjonsuttrykkmønsteret- eller ved å deklarere variabelen ved å bruke letsøkeordet.

Erklæring og oppgave

Variabler deklarert utenfor et virkeområde er globale . Hvis en variabel deklareres i et høyere omfang, kan den nås via barneskalaer.

Når JavaScript prøver å løse en identifikator, ser det ut i det lokale omfanget. Hvis denne identifikatoren ikke blir funnet, ser den i neste ytre omfang, og så videre langs omfangskjeden til den når det globale omfanget der globale variabler ligger. Hvis det fremdeles ikke blir funnet, vil JavaScript gjøre et ReferenceErrorunntak.

Når du tilordner en identifikator, går JavaScript gjennom nøyaktig den samme prosessen for å hente denne identifikatoren, bortsett fra at hvis den ikke finnes i det globale omfanget , vil den opprette "variabelen" i omfanget der den ble opprettet. Som en konsekvens vil en variabel som aldri er deklarert være global, hvis den er tilordnet. Erklæring av en variabel (med søkeordet var) i det globale omfanget (dvs. utenfor et funksjonsorgan (eller blokk i tilfelle av let/const)), tilordne en aldri deklarert identifikator eller legge en eiendom til det globale objektet (vanligvis vindu ) vil også lage en ny global variabel.

Vær oppmerksom på at JavaScripts strenge modus forbyr tildeling av en ikke -deklarert variabel, som unngår forurensning av verdensrommet.

Eksempler

Her er noen eksempler på variable deklarasjoner og omfang:

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

Primitive datatyper

JavaScript -språket gir seks primitive datatyper :

  • Udefinert
  • Nummer
  • BigInt
  • String
  • Boolsk
  • Symbol

Noen av de primitive datatypene gir også et sett med navngitte verdier som representerer omfanget av typegrensene. Disse navngitte verdiene er beskrevet i de aktuelle seksjonene nedenfor.

Udefinert

Den verdien av "udefinert" er tildelt alle initialisert variabler , og er også returneres når du sjekker for objektegenskaper som ikke eksisterer. I en boolsk kontekst regnes den udefinerte verdien som en falsk verdi.

Merk: udefinert regnes som en ekte primitiv type. Med mindre den eksplisitt konverteres, kan den udefinerte verdien oppføre seg uventet i forhold til andre typer som vurderes til usanne i en logisk kontekst.

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

Merk: Det er ingen innebygd språk bokstavelig for udefinert. Dermed er det ikke en idiotsikker måte å kontrollere om en variabel er udefinert, for i versjoner før ECMAScript 5 er det lovlig for noen å skrive . En mer robust tilnærming er å sammenligne med . (x === undefined)var undefined = "I'm defined now";(typeof x === 'undefined')

Funksjoner som dette fungerer ikke som forventet:

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

Her ringer det isUndefined(my_var)opp en ReferenceError hvis my_var er en ukjent identifikator, mens den ikke gjør det. typeof my_var === 'undefined'

Nummer

Tall er representert i binær som IEEE-754 flytende dobler. Selv om dette formatet gir en nøyaktighet på nesten 16 signifikante sifre , kan det ikke alltid nøyaktig representere reelle tall, inkludert brøk.

Dette blir et problem når du sammenligner eller formaterer tall. For eksempel:

console.log(0.2 + 0.1 === 0.3); // displays false
console.log(0.94 - 0.01);       // displays 0.9299999999999999

Som et resultat bør en rutine som toFixed () -metoden brukes til å avrunde tall når de formateres for utdata .

Tall kan spesifiseres i en av disse notasjonene:

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

Det er også en numerisk separator, _ (understrekningen), introdusert i 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

Omfangene +∞ , −∞ og NaN (Ikke et tall) av nummertypen kan oppnås ved to programuttrykk:

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

Uendelig og NaN er tall:

typeof Infinity;   // returns "number"
typeof NaN;        // returns "number"

Disse tre spesielle verdiene samsvarer og oppfører seg slik IEEE-754 beskriver dem.

Tallkonstruktøren (brukt som funksjon), eller unary + eller -, kan brukes til å utføre eksplisitt numerisk konvertering:

var myString = "123.456";
var myNumber1 = Number(myString);
var myNumber2 = +myString;

Når det brukes som konstruktør, opprettes et numerisk innpakningsobjekt (selv om det er til liten nytte):

myNumericWrapper = new Number(123.456);

NaN er imidlertid ikke lik seg selv:

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 kan brukes for vilkårlig store heltall . Spesielt hele tall større enn 2 53 - 1, som er det største tallet JavaScript på en pålitelig måte kan representere med tallet primitivt og representert med konstanten Number.MAX_SAFE_INTEGER.

Når du deler BigInts, blir resultatene avkortet .

String

En streng i JavaScript er en sekvens av tegn. I JavaScript kan strenger opprettes direkte (som bokstavelig talt) ved å plassere tegnserien mellom doble (") eller enkle (') anførselstegn. Slike strenger må skrives på en enkelt linje, men kan inneholde rømte nylinjetegn (for eksempel \ n). JavaScript -standarden tillater backquote -tegnet (`, alias grav aksent eller tilbakeslag) for å sitere bokstaver med flere linjer, men dette støttes bare i visse nettlesere fra og med 2016: Firefox og Chrome, men ikke Internet Explorer 11.

var greeting = "Hello, World!";
var anotherGreeting = 'Greetings, people of Earth.';

Individuelle tegn i en streng kan nås ved hjelp av charAt -metoden (levert av String.prototype ). Dette er den foretrukne måten når du får tilgang til individuelle tegn i en streng, fordi den også fungerer i ikke-moderne nettlesere:

var h = greeting.charAt(0);

I moderne nettlesere kan du få tilgang til individuelle tegn i en streng (som strenger med bare et tegn) gjennom samme notasjon som arrays:

var h = greeting[0];

Imidlertid er JavaScript -strenger uforanderlige :

greeting[0] = "H"; // Fails.

Å bruke likhetsoperatoren ("==") på to strenger returnerer true, hvis strengene har samme innhold, noe som betyr: av samme lengde og som inneholder samme tegnrekke (store bokstaver er viktige for alfabeter). Og dermed:

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.

Sitater av samme type kan ikke hekkes med mindre de slipper unna .

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 \"

Den String konstruktøren skaper en streng objekt (et objekt vikle en streng):

var greeting = new String("Hello, World!");

Disse objektene har en valueOf -metode som returnerer den primitive strengen som er pakket inn i dem:

var s = new String("Hello !");
typeof s; // Is 'object'.
typeof s.valueOf(); // Is 'string'.

Likhet mellom to strengobjekter oppfører seg ikke som med strengprimitiver:

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.

Boolsk

JavaScript gir en boolsk datatype med sanne og falske bokstaver. Den typeof operatør returnerer strengen "boolsk" for disse primitive typer . Når den brukes i en logisk kontekst, vurderes 0 , -0 , null , NaN , udefinert og den tomme strengen ( "" ) som usann på grunn av automatisk type tvang . Alle andre verdier ( komplementet til forrige liste) vurderes som sanne , inkludert strengene "0" , "usanne" og ethvert objekt.

Type konvertering

Automatisk typetvang av likestillingssammenligningsoperatørene ( ==og !=) kan unngås ved å bruke typekontrollerte sammenligningsoperatorer ( ===og !==).

Når typekonverterings er nødvendig, omdanner Java boolsk , Number , streng , eller objekt- operander som følger:

Nummer og streng
Strengen konverteres til en tallverdi. JavaScript prøver å konvertere strengen numerisk bokstavelig til en talltypeverdi. Først er en matematisk verdi avledet fra strengen numerisk bokstavelig. Deretter avrundes denne verdien til nærmeste talltypeverdi.
Boolsk
Hvis en av operandene er en boolsk, konverteres den boolske operanden til 1 hvis den er sann , eller til 0 hvis den er usann .
Gjenstand
Hvis et objekt blir sammenlignet med et tall eller en streng, prøver JavaScript å returnere standardverdien for objektet. Et objekt konverteres til en primitiv streng eller tallverdi ved hjelp av .valueOf () eller .toString () metodene for objektet. Hvis dette mislykkes, genereres en kjøretidsfeil.

Douglas Crockford tar til orde for begrepene " sannhet " og " falsk " for å beskrive hvordan verdier av forskjellige typer oppfører seg når de evalueres i en logisk kontekst, spesielt når det gjelder kanttilfeller . De binære logiske operatørene returnerte en boolsk verdi i tidlige versjoner av JavaScript, men nå returnerer de en av operandene i stedet. Venstre -operanden returneres, hvis den kan vurderes som: falsk , i tilfelle av konjunksjon : ( a && b), eller sant , i tilfelle av disjunction : ( a || b); ellers returneres rett -operand. Automatisk type tvang av sammenligningsoperatørene kan variere for tilfeller av blandede boolske og tallkompatible operander (inkludert strenger som kan evalueres som et tall, eller objekter som kan evalueres som en slik streng), fordi den boolske operanden vil bli sammenlignet med en numerisk verdi. Dette kan være uventet. Et uttrykk kan eksplisitt kastes til en boolsk primitiv ved å doble den logiske negasjonsoperatoren : ( !! ), bruke funksjonen boolsk () eller ved å bruke den betingede operatoren : ( 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"

Den nye operatøren kan brukes til å lage en objektinnpakning for en boolsk primitiv. Men typeof ikke operatøren ikke tilbake boolsk for objektet wrapper, returnerer objekt . Fordi alle objekter evalueres som sanne , må en metode som .valueOf () eller .toString () brukes for å hente inn den omsluttede verdien. For eksplisitt tvang til den boolske typen, anbefaler Mozilla at den boolske () -funksjonen (uten ny ) brukes i stedet for det boolske objektet.

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");
}

Symbol

Nytt i ECMAScript6. Et symbol er en unik og uforanderlig identifikator.

Eksempel:

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

Det er også velkjente symboler .

En av dem er Symbol.iterator; hvis noe implementeres Symbol.iterator, er det gjentatt:

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"
}

Innfødte gjenstander

JavaScript -språket gir en håndfull opprinnelige objekter . JavaScript -opprinnelige objekter regnes som en del av JavaScript -spesifikasjonen. Uansett JavaScript -miljø, bør dette settet med objekter alltid være tilgjengelig.

Array

An Array er et JavaScript -objekt prototypet fra Array -konstruktøren spesielt designet for å lagre dataverdier indeksert av heltallsnøkler. Matriser, i motsetning til den grunnleggende objekttypen, er prototypet med metoder og egenskaper for å hjelpe programmereren med rutinemessige oppgaver (for eksempel bli med , skjær og trykk ).

Som i C-familien bruker matriser et nullbasert indekseringsopplegg: En verdi som settes inn i en tom matrise ved hjelp av push- metoden opptar den niende indeksen i matrisen.

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");

Arrays har en lengdeegenskap som garantert alltid vil være større enn den største heltallindeksen som brukes i matrisen. Den oppdateres automatisk hvis man oppretter en eiendom med en enda større indeks. Hvis du skriver et mindre tall til lengdeegenskapen , fjernes større indekser.

Elementer av Array s kan nås ved hjelp av normal notattilgangsnotasjon:

myArray[1];  // the 2nd item in myArray
myArray["1"];

De to ovennevnte er likeverdige. Det er ikke mulig å bruke "prikk" -notasjonen eller strengene med alternative representasjoner av tallet:

myArray.1;     // syntax error
myArray["01"]; // not the same as myArray[1]

Erklæring om en matrise kan enten bruke en Array -bokstav eller Array -konstruktøren:

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

Matriser implementeres slik at bare de definerte elementene bruker minne; de er " sparsomme matriser ". Innstilling og bruker bare plass til disse to elementene, akkurat som alle andre objekter. Den lengde av tabellen vil fortsatt bli rapportert som 58. Den maksimale lengde av en matrise er 4294967295, som korresponderer med 32-bits binærtall (11111111111111111111111111111111) 2 . myArray[10] = 'someThing'myArray[57] = 'somethingOther'

Man kan bruke objektdeklarasjonen bokstavelig til å lage objekter som oppfører seg omtrent som assosiative matriser på andre språk:

dog = {color: "brown", size: "large"};
dog["color"]; // results in "brown"
dog.color;    // also results in "brown"

Man kan bruke objekt- og matrisedeklarasjonsbokstavene til raskt å lage matriser som er assosiative, flerdimensjonale eller begge deler. (Teknisk støtter JavaScript ikke flerdimensjonale matriser, men man kan etterligne dem med matriser-av-matriser.)

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"

Dato

En Dato objekt lagrer en signert millisekund telling med null som representerer 1970-01-01 00:00:00 UT og et område på ± 10 8 dager. Det er flere måter å komme med argumenter til Date -konstruktøren. Vær oppmerksom på at månedene er nullbaserte.

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.

Det finnes metoder for å trekke ut felt, samt en nyttig toString :

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);

Feil

Custom feilmeldinger kan opprettes ved hjelp av feil klasse:

throw new Error("Something went wrong.");

Disse kan fanges ved å prøve ... fange ... til slutt blokker som beskrevet i avsnittet om unntakshåndtering .

Matte

Den Math objektet inneholder forskjellige matematiske-relaterte konstanter (f.eks rc ) og funksjoner (for eksempel cosinus). (Vær oppmerksom på at matematikkobjektet ikke har noen konstruktør, i motsetning til Array eller Date . Alle metodene er "statiske", det vil si "klasse" -metoder.) Alle trigonometriske funksjoner bruker vinkler uttrykt i radianer , ikke grader eller grader .

Noen av konstantene i matematikkobjektet
Eiendom Returnert verdi
avrundet til 5 sifre
Beskrivelse
Math.E 2,7183 e : Naturlig logaritmbase
Math.LN2 0,69315 Naturlig logaritme av 2
Math.LN10 2.3026 Naturlig logaritme på 10
Math.LOG2E 1.4427 Logaritme til base 2 av e
Math.LOG10E 0,43429 Logaritme til basen 10 av e
Math.PI 3.14159 π : omkrets/diameter av en sirkel
Math.SQRT1_2 0,70711 Kvadratrot på ½
Math.SQRT2 1.4142 Kvadratrot av 2
Metoder for matematikkobjektet
Eksempel Returnert verdi
avrundet til 5 sifre
Beskrivelse
Math.abs (-2.3) 2.3 Absolutt verdi
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 ° Halvsirkel arctangent (- π /2 til + π /2)
Math.atan2 (-3.7, -3.7) -2,3562 rad. = -135 ° Hele sirkelen arctangent (- π til + π )
Math.ceil (1.1) 2 Tak: runde opp til minste heltall ≥ argument
Math.cos (Math.PI/4) 0,70711 Kosinus
Math.exp (1) 2,7183 Eksponensiell funksjon : e hevet til denne kraften
Matematikkgulv (1.9) 1 Etasje: runde ned til største heltall ≤ argument
Math.log (Math.E) 1 Naturlig logaritme, base e
Matematikk. Maks (1, -2) 1 Maksimum: (x> y)? x: y
Math.min (1, -2) -2 Minimum: (x <y)? x: y
Matematikkpow (-3, 2) 9 Eksponentiering (hevet til kraften til): Math.pow (x, y) gir x y
Math.random () f.eks. 0.17068 Pseudotilfeldig nummer mellom 0 (inkludert) og 1 (eksklusivt)
Math.round (1.5) 2 Rund til nærmeste heltall; halve brøk avrundes (f.eks. 1,5 runder til 2)
Math.sin (Math.PI/4) 0,70711 Sinus
Matematikk.sqrt (49) 7 Kvadratrot
Math.tan (Math.PI/4) 1 Tangent

Vanlig uttrykk

/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"

Karakterklasser

// \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');

Tegnmatching

// 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');

Repeatere

// ?   - 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"

Anker

// ^  - 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!");

Subexpression

// ( )  - 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!");

Flagg

// /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"

Avanserte metoder

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"];

Fange grupper

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!");

Funksjon

Hver funksjon i JavaScript er en forekomst av funksjonskonstruktøren :

// 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

Add -funksjonen ovenfor kan også defineres ved hjelp av et funksjonsuttrykk:

var add = function(x, y) {
  return x + y;
};
add(1, 2); // => 3

I ES6 ble syntaks for pilfunksjonen lagt til, slik at funksjoner som returnerer en verdi kan være mer konsise. De beholder også dette til det globale objektet i stedet for å arve det der det ble kalt / det det ble kalt på, i motsetning til funksjonen () {} uttrykket.

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

For funksjoner som må heises, er det et eget uttrykk:

function add(x, y) {
  return x + y;
}
add(1, 2); // => 3

Heising lar deg bruke funksjonen før den "deklareres":

add(1, 2); // => 3, not a ReferenceError
function add(x, y) {
  return x + y;
}

En funksjonsforekomst har egenskaper og metoder.

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;
}"
*/

Operatører

Operatøren '+' er overbelastet : den brukes til strengkobling og aritmetisk tillegg. Dette kan forårsake problemer ved utilsiktet blanding av strenger og tall. Som en unary operator kan den konvertere en numerisk streng til et tall.

// 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

På samme måte er "*" -operatoren overbelastet: den kan konvertere en streng til et tall.

console.log(2 + '6'*1);  // displays 8
console.log(3*'7'); // 21
console.log('3'*'7'); // 21
console.log('hello'*'world'); // displays NaN

Aritmetikk

JavaScript støtter følgende binære aritmetiske operatorer :

+ addisjon
- subtraksjon
* multiplikasjon
/ divisjon (returnerer en flytende verdi)
% modulo (returnerer resten)
** eksponensiering

JavaScript støtter følgende unary arithmetic operatorer :

+ unary konvertering av streng til tall
- unary negation (reverserer tegnet)
++ inkrement (kan være prefiks eller postfiks)
- reduksjon (kan være prefiks eller postfiks)
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

Modulo -operatøren viser resten etter divisjon med modulen. Hvis negative tall er involvert, avhenger verdien som returneres av operanden.

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

For å alltid returnere et ikke-negativt tall, legg til modulen på nytt og bruk modulo-operatøren igjen:

var x = 17;
console.log((-x%5+5)%5); // displays 3

Oppdrag

= tildele
+= legge til og tildele
-= trekke fra og tildele
*= multiplisere og tildele
/= dele og tildele
%= modulo og tilordne
** = eksponentiering og tilordne

Tildeling av primitive typer

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

Tildeling av objekttyper

/**
 * 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);
}

Destruktureringsoppgave

I Mozillas JavaScript, siden versjon 1.7, tillater destruktureringsoppdrag tildeling av deler av datastrukturer til flere variabler samtidig. Venstre side av en oppgave er et mønster som ligner et vilkårlig nestet objekt/matrise bokstavelig inneholdende l-l-verdier på bladene som skal motta understrukturene til den tildelte verdien.

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

Spreder/hvil operatør

ECMAScript 2015 -standarden introduserer operatøren " ... " for de relaterte begrepene "spredningssyntaks" og "hvileparametere"

Spreadsyntaks gir en annen måte å ødelegge matriser på. Det indikerer at elementene i en spesifisert matrise skal brukes som parametrene i et funksjonsanrop eller elementene i en matrise bokstavelig talt.

Med andre ord, " ... " forvandler " [... foo] " til " [foo [0], foo [1], foo [2]] " og " this.bar (... foo); "inn" i denne. 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"

Når ... blir brukt i en funksjon erklæring , indikerer det en hvile parameter . Restparameteren må være den siste navngitte parameteren i funksjonens parameterliste. Det vil bli tildelt en matrise som inneholder alle argumenter som overføres til funksjonen utover de andre navngitte parametrene. Med andre ord får den "resten" av argumentene videre til funksjonen (derav navnet).

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 = []

Restparametere ligner Javascripts argumentobjekt , som er et array-lignende objekt som inneholder alle parameterne (navngitt og ikke navngitt) i det gjeldende funksjonsanropet. I motsetning til argumenter er imidlertid hvileparametere sanne Array -objekter, så metoder som .slice () og .sort () kan brukes på dem direkte.

Den ... Operatøren kan bare brukes med Array stedene. (Det er imidlertid et forslag om å utvide det til Object s i en fremtidig ECMAScript -standard.)

Sammenligning

== lik
! = ikke lik
> større enn
> = større enn eller lik
< mindre enn
<= mindre enn eller lik
=== identisk (lik og av samme type)
! == ikke identisk

Variabler som refererer til objekter er like eller identiske bare hvis de refererer til det samme objektet:

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

Se også String .

Logisk

JavaScript gir fire logiske operatører:

I konteksten for en logisk operasjon evaluerer ethvert uttrykk til sant bortsett fra følgende :

  • Strenger: "" , '' ,
  • Tall: 0 , -0 , NaN ,
  • Spesielt: null , udefinert ,
  • Boolsk: falsk .

Den boolske funksjonen kan brukes til å eksplisitt konvertere til en primitiv av typen boolsk :

// 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()

NOT -operatøren vurderer operanden som en booleske og returnerer negasjonen. Ved å bruke operatøren to ganger på rad, som et dobbeltnegativ , konverterer eksplisitt et uttrykk til en primitiv av typen boolsk:

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"));

Den ternære operatøren kan også brukes til eksplisitt konvertering:

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

Uttrykk som bruker funksjoner som post -inkrementering ( i ++ ) har en forventet bivirkning . JavaScript gir kortslutningsevaluering av uttrykk; høyre operand utføres bare hvis venstre operand ikke er tilstrekkelig til å bestemme verdien av uttrykket.

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.

I tidlige versjoner av JavaScript og JScript returnerte de binære logiske operatorene en boolsk verdi (som de fleste C-avledede programmeringsspråk). Imidlertid returnerer alle samtidige implementeringer en av operandene i stedet:

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

Programmerere som er mer kjent med oppførselen i C, kan synes denne funksjonen er overraskende, men den gir et mer konsist uttrykk for mønstre som null -koalesering :

var s = t || "(default)"; // assigns t, or the default value, if t is null, empty, etc.

Logisk oppgave

?? = Uklar oppgave
|| = Logisk eller oppgave
&& = Logisk og oppgave

Bitvis

JavaScript støtter følgende binære bitvise operatører :

& OG
| ELLER
^ XOR
! IKKE
<< skift til venstre (null fylling til høyre)
>> skifte til høyre (skiltformere); kopier av
biten lengst til venstre (tegnbit) flyttes inn fra venstre
>>> skift til høyre (null fylling til venstre). For positive tall gir
>> og >>> samme resultat.

Eksempler:

x=11 & 6;
console.log(x); // 2

JavaScript støtter følgende unary bitvise operatør :

~ IKKE (inverterer bitene)

Bitvis oppgave

JavaScript støtter følgende binære oppdragsoperatører:

& = og
| = eller
^= xor
<< = skift til venstre (null fylling til høyre)
>> = skifte til høyre (skiltformere); kopier av
biten lengst til venstre (tegnbit) flyttes inn fra venstre
>>> = skift til høyre (null fylling til venstre). For positive tall gir
>> = og >>> = samme resultat.

Eksempler:

x=7;
console.log(x); // 7
x<<=3;
console.log(x); // 7->14->28->56

String

= oppdrag
+ sammenkobling
+= sammenkoble og tildele

Eksempler:

str = "ab" + "cd";  // "abcd"
str += "e";      // "abcde"

str2 = "2" + 2;     // "22", not "4" or 4.

??

Den nærmeste operatøren til JavaScript er ??"nullish coalescing operator", som ble lagt til standarden i ECMAScripts 11. utgave. I tidligere versjoner kan den brukes via et Babel -plugin og i TypeScript . Den evaluerer sin venstre operand, og hvis resultatverdien ikke er "null" ( nulleller undefined), tar den verdien som sitt resultat; Ellers evaluerer den høyre operand og tar den resulterende verdien som resultat.

I det følgende eksemplet avil verdien bli tildelt bhvis verdien av bikke er nulleller undefined, ellers vil den bli tildelt 3.

const a = b ?? 3;

Før den nullish coalescing -operatøren ville programmerere bruke den logiske OR -operatoren ( ||). Men der ??ser spesielt for nulleller undefinedde ||operatør ser for noen falsy verdi: null, undefined, "", 0, NaN, og selvfølgelig false.

I det følgende eksemplet avil verdien bli tildelt bhvis verdien av ber sann , ellers vil den bli tildelt 3.

const a = b || 3;

Kontrollstrukturer

Sammensatte uttalelser

Et par krøllete parenteser {} og en vedlagt sekvens av setninger utgjør en sammensatt setning som kan brukes hvor som helst en setning kan brukes.

Hvis ... annet

if (expr) {
  //statements;
} else if (expr2) {
  //statements;
} else {
  //statements;
}

Betinget (ternær) operatør

Den betingede operatøren oppretter et uttrykk som evalueres som ett av to uttrykk, avhengig av en tilstand. Dette ligner på if -setningen som velger en av to setninger som skal kjøres, avhengig av en tilstand. Dvs, er den betingede operatør til uttrykk hva om er til uttalelser.

 result = condition ? expression : alternative;

er det samme som:

 if (condition) {
  result = expression;
 } else {
  result = alternative;
 }

I motsetning til if- setningen kan ikke den betingede operatøren utelate sin "else-gren".

Bytt uttalelse

Syntaksen til JavaScript -switch -setningen er som følger:

 switch (expr) {
  case SOMEVALUE:
   // statements;
   break;
  case ANOTHERVALUE:
   // statements;
   break;
  default:
   // statements;
   break;
 }
  • gå i stykker; er valgfritt; Imidlertid er det vanligvis nødvendig, siden kodeutførelsen ellers fortsetter til hoveddelen av den neste saksblokken.
  • Legg til en pauseerklæring til slutten av den siste saken som et forholdsregel, hvis flere tilfeller legges til senere.
  • String bokstavelige verdier kan også brukes for saksverdiene.
  • Uttrykk kan brukes i stedet for verdier.
  • Standardtilfellet (valgfritt) utføres når uttrykket ikke samsvarer med andre angitte tilfeller.
  • Seler kreves.

For sløyfe

Syntaksen til JavaScript for loop er som følger:

 for (initial; condition; loop statement) {
  /*
   statements will be executed every time
   the for{} loop cycles, while the
   condition is satisfied
  */
 }

eller

 for (initial; condition; loop statement(iteration)) // one statement

For ... i løkke

Syntaksen til JavaScript for ... in looper som følger:

for (var property_name in some_object) {
  // statements using some_object[property_name];
}
  • Itererer gjennom alle de talløse egenskapene til et objekt.
  • Skifter gjennom alle brukte matriseindekser, inkludert alle brukerdefinerte egenskaper for matriseobjekt, hvis noen. Dermed kan det være bedre å bruke en tradisjonell sløyfe med en numerisk indeks når den gjentar seg over matriser.
  • Det er forskjeller mellom de forskjellige nettleserne med hensyn til hvilke egenskaper som vil reflekteres med for ... in loop -setningen. I teorien styres dette av en intern tilstandseiendom definert av ECMAscript -standarden kalt "DontEnum", men i praksis returnerer hver nettleser et litt annet sett med egenskaper under introspeksjon. Det er nyttig å teste for en gitt egenskap ved å bruke }. Dermed kan det å legge til en metode til matriseprototypen med } føre til at løkker sløyfes over metodens navn.if (some_object.hasOwnProperty(property_name)) { ...Array.prototype.newMethod = function() {...for ... in

Mens sløyfe

Syntaksen til JavaScript mens loop er som følger:

while (condition) {
  statement1;
  statement2;
  statement3;
  ...
}

Gjør ... mens sløyfe

Syntaksen til JavaScript do ... while looper som følger:

do {
  statement1;
  statement2;
  statement3;
  ...
} while (condition);

Med

Med -setningen legger alle egenskapene og metodene til det gitte objektet inn i den følgende blokkens omfang, slik at det kan refereres til dem som om de var lokale variabler.

with (document) {
  var a = getElementById('a');
  var b = getElementById('b');
  var c = getElementById('c');
};
  • Legg merke til fraværet av dokument. før hver påkallelse fra getElementById () .

Semantikken ligner på med Pascal .

Fordi tilgjengeligheten av med utsagn hindrer programytelsen og antas å redusere kodeklarheten (siden en gitt variabel faktisk kan være en egenskap fra en vedlegg med ), er denne uttalelsen ikke tillatt i streng modus .

Etiketter

JavaScript støtter nestede etiketter i de fleste implementeringer. Løkker eller blokker kan merkes for pausesetningen, og løkker for fortsettelse . Selv om goto er et reservert ord, er goto ikke implementert i 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.

Funksjoner

En funksjon er en blokk med en (muligens tom) parameterliste som normalt får et navn. En funksjon kan bruke lokale variabler. Hvis du avslutter funksjonen uten en returoppgave, returneres den udefinerte verdien .

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

Funksjoner er førsteklasses objekter og kan tilordnes andre variabler.

Antall argumenter gitt når du kaller til en funksjon, trenger ikke nødvendigvis å stemme overens med antall argumenter i funksjonsdefinisjonen; et navngitt argument i definisjonen som ikke har et matchende argument i samtalen, vil ha verdien udefinert (som implisitt kan kastes til usann). Innen funksjonen kan du også få tilgang til argumentene gjennom argumentobjektet ; dette gir tilgang til alle argumenter ved hjelp av indekser (f.eks. ), inkludert de som ligger utenfor antallet navngitte argumenter. (Selv om argumentlisten har en .length -egenskap, er den ikke en forekomst av Array ; den har ikke metoder som .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

Primitive verdier (tall, boolsk, streng) passeres etter verdi. For objekter er det referansen til objektet som sendes.

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

Funksjoner kan deklareres inne i andre funksjoner, og få tilgang til de ytre funksjonens lokale variabler. Videre implementerer de fullstendige nedleggelser ved å huske den eksterne funksjonens lokale variabler selv etter at den ytre funksjonen er avsluttet.

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

Asynkroniser/venter

Vent -operatøren i JavaScript kan bare brukes fra innsiden av en asynkroniseringsfunksjon. Hvis parameteren er et løfte , vil utførelsen av asynkroniseringsfunksjonen gjenopptas når løftet er løst (med mindre løftet blir avvist, i så fall vil en feil bli kastet som kan håndteres med vanlig JavaScript -unntakshåndtering ). Hvis parameteren ikke er et løfte, blir selve parameteren returnert umiddelbart.

Mange biblioteker gir løfteobjekter som også kan brukes med vente, så lenge de samsvarer med spesifikasjonen for native JavaScript -løfter. Løfter fra jQuery -biblioteket var imidlertid ikke Promises/A+ -kompatible før jQuery 3.0.

Her er et eksempel (endret fra denne artikkelen):

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();
Node.js versjon 8 inneholder et verktøy som gjør det mulig å bruke standardbibliotekets tilbakeringingsbaserte metoder som løfter.

Objekter

For enkelhets skyld er typer vanligvis delt inn i primitiver og objekter . Objekter er enheter som har en identitet (de er bare lik dem selv) og som tilordner eiendomsnavn til verdier ("spor" i prototypebasert programmeringsterminologi ). Objekter kan betraktes som assosiative arrays eller hashes, og implementeres ofte ved hjelp av disse datastrukturer. Objekter har imidlertid tilleggsfunksjoner, for eksempel en prototypekjede, som vanlige assosiative matriser ikke har.

JavaScript har flere typer innebygde objekter, nemlig Array , Boolean , Date , Function , Math , Number , Object , RegExp og String . Andre objekter er "vertsobjekter", definert ikke av språket, men av kjøretidsmiljøet. For eksempel tilhører typiske vertsobjekter i en nettleser DOM (vindu, skjema, lenker, etc.).

Å lage objekter

Objekter kan opprettes ved hjelp av en konstruktør eller et bokstavelig objekt. Konstruktøren kan enten bruke en innebygd objektfunksjon eller en egendefinert funksjon. Det er en konvensjon at konstruktorfunksjoner får et navn som starter med stor bokstav:

// 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)

Objektlitteraler og matriselitteraler lar en enkelt lage fleksible datastrukturer:

var myStructure = {
  name: {
    first: "Mel",
    last: "Smith"
  },
  age: 33,
  hobbies: ["chess", "jogging"]
};

Dette er grunnlaget for JSON , som er en enkel notasjon som bruker JavaScript-lignende syntaks for datautveksling.

Metoder

En metode er ganske enkelt en funksjon som har blitt tilordnet et eiendomsnavn for et objekt. I motsetning til mange objektorienterte språk, er det ikke noe skille mellom en funksjonsdefinisjon og en metodedefinisjon i objektrelatert JavaScript. Snarere skjer skillet under funksjonskall; en funksjon kan kalles som en metode.

Når kalles som en metode, den standard lokal variabel dette bare er automatisk satt til objektet forekomsten til venstre for " ". (Det er også metoder for anrop og anvendelse som kan angi dette eksplisitt - noen pakker som jQuery gjør uvanlige ting med dette .)

I eksemplet nedenfor brukes Foo som konstruktør. Det er ikke noe spesielt med en konstruktør - det er bare en vanlig funksjon som initialiserer et objekt. Når den brukes med nye søkeord, er som norm, denne er satt til en nyopprettet tomt objekt.

Vær oppmerksom på at i eksemplet nedenfor tilordner Foo ganske enkelt verdier til spor, hvorav noen er funksjoner. Dermed kan den tilordne forskjellige funksjoner til forskjellige forekomster. Det er ingen prototyper i dette eksemplet.

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.

Konstruktører

Konstruktorfunksjoner tildeler ganske enkelt verdier til sporene til et nyopprettet objekt. Verdiene kan være data eller andre funksjoner.

Eksempel: Manipulere et objekt:

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

Selve konstruktøren refereres til objektets prototypes konstruktorspor . Så,

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.

Funksjoner er objekter selv, som kan brukes til å produsere en effekt som ligner på "statiske egenskaper" (ved bruk av C ++/Java -terminologi) som vist nedenfor. (Funksjonsobjektet har også en spesiell prototypegenskap , som diskutert i delen "Arv" nedenfor.)

Sletting av objekter brukes sjelden, ettersom skriptmotoren vil samle gjenstander som det ikke lenger refereres til.

Arv

Javascript støtter arv hierarkier gjennom prototyping i form av selv .

I det følgende eksemplet arver den avledede klassen fra baseklassen . Når d opprettes som Derived , kopieres referansen til basisforekomsten av Base til d.base .

Derive inneholder ikke en verdi for aBaseFunction , så den hentes fra aBaseFunction når du får tilgang til aBaseFunction . Dette blir tydeliggjort ved å endre verdien av base.aBaseFunction , som gjenspeiles i verdien av d.aBaseFunction .

Noen implementeringer gjør at prototypen kan nås eller angis eksplisitt ved hjelp av __proto__ -sporet som vist nedenfor.

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.

Det følgende viser tydelig hvordan referanser til prototyper kopieres på opprettelse av forekomster, men at endringer i en prototype kan påvirke alle forekomster som refererer til den.

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

I praksis brukes mange varianter av disse temaene, og det kan være både kraftig og forvirrende.

Avvikshåndtering

JavaScript inkluderer en try ... catch ... finally unntakshåndteringserklæring for å håndtere kjøretidsfeil.

Den try ... catch ... finallysetningen fanger unntak som følge av en feil eller et kast regnskapet. Syntaksen er som følger:

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
}

I utgangspunktet utføres utsagnene i prøveblokken. Hvis et unntak kastes, overføres skriptets kontrollflyt umiddelbart til setningene i fangstblokken, med unntaket tilgjengelig som feilargument. Ellers blir fangstblokken hoppet over. Fangstblokken kan kaste (errorValue) hvis den ikke ønsker å håndtere en bestemt feil.

Uansett blir uttalelsene i den endelige blokken alltid utført. Dette kan brukes til å frigjøre ressurser, selv om minnet automatisk samles søppel.

Enten fangsten eller endelig klausul kan utelates. Fangargumentet er påkrevd.

Mozilla -implementeringen gir mulighet for flere fangstuttalelser, som en forlengelse av ECMAScript -standarden. De følger en syntaks som ligner den som brukes i Java :

try { statement; }
catch (e if e == "InvalidNameException")  { statement; }
catch (e if e == "InvalidIdException")    { statement; }
catch (e if e == "InvalidEmailException") { statement; }
catch (e)                                 { statement; }

I en nettleser er hendelsen onerror mer vanlig for å fange unntak.

onerror = function (errorValue, url, lineNr) {...; return true;};

Innfødte funksjoner og metoder

(Ikke relatert til nettlesere.)

eval (uttrykk)

Evaluerer den første parameteren som et uttrykk, som kan inkludere oppgavesetninger. Variabler som er lokale for funksjoner, kan refereres til av uttrykket. Imidlertid evalrepresenterer den en stor sikkerhetsrisiko, ettersom den tillater en dårlig aktør å utføre vilkårlig kode, så bruk av den frarådes.

(function foo() {
  var x = 7;
  console.log("val " + eval("x + 2"));
})(); // shows val 9.

Se også

Referanser

Videre lesning

  • 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: Taler JavaScript: En dybdeveiledning for programmerere , 460 sider, O'Reilly Media, 25. februar 2014, ISBN  978-1449365035 . ( gratis online utgave )
  • Emily Vander Veer: JavaScript For Dummies, 4. utgave , Wiley, ISBN  0-7645-7659-3 .

Eksterne linker