Grammar and types

Dit hoofdstuk behandelt de basics van de JavaScript grammatica, declaratie van variabelen, datatypen en literalen.

Basis

De syntax van JavaScript heeft veel weg van Java, maar is ook beïnvloed door Awk, Perl en Python.

JavaScript is hoofdlettergevoelig en maakt gebruik van de Unicode-tekenset.

In JavaScript worden instructies statements genoemd. Deze worden gescheiden door een puntkomma (;). Spaties, tabs en regeleinden worden whitespaces genoemd. De broncode van JavaScript wordt gescanned van links naar rechts en wordt geconverteerd in een rij van input elementen ofwel tokens, control characters, line terminators, opmerkingen of whitespaces. ECMAScript definieert ook bepaalde keywords en literalen en heeft regels voor het automatisch invoegen van puntkomma's (ASI) aan het eine van statements. Echter, het is aanbevolen om altijd puntkomma's aan het einde van statements te plaatsen; dit voorkomt neveneffecten. Voor meer informatie, zie de gedetailleerde referentie over de lexical grammar van JavaScript.

Opmerkingen

De syntax van opmerkingen is hetzelfde als in C++ en veel andere programmeertalen:

// 1-regel opmerking
 
/* dit is een langere,
   meerdere regels opmerking
 */
 
/* Je kan opmerkingen /* niet nesten */ SyntaxError */

Declaraties

Er zijn drie soorten declaraties in JavaScript.

var
Declareer een variabele en mogelijk initialiseren naar een waarde.
let
Declareer een block scope variabele en mogelijk initialiseren naar een waarde.
const
Declareer een alleen-lezen benoemde constante.

Variabelen

Je kunt variabelen gebruiken als symbolische waarden in je applicatie. De namen van variabelen, genaamd identifiers, voldoen aan bepaalde conventies.

Een JavaScript identifier moet beginnen met een letter, underscore (_) of dollarteken ($); volgende karakters kunnen ook nummers zijn (0-9). Omdat JavaScript hoofdlettergevoelig is, behoren tot de letters karakters "A" tot en met "Z" (hoofdletters) en de karakters "a" tot en met "z" (kleine letters).

Je kunt ISO 8859-1 of Unicode letters zoals å en ü gebruiken in identifiers. Je kunt ook de Unicode escape sequences als karakters gebruiken in identifiers.

Voorbeelden van toegestane namen zijn Aantal_hits, temp99, en _naam.

Variabelen declareren

Je kunt variabelen declareren op drie manieren:

  • Met het keywordvar. Bijvoorbeeld var x = 42. Deze syntax kan worden gebruikt voor het declareren van zowel lokale als globale variabelen.
  • Door simpelweg een waarde toe te wijzen. Bijvoorbeeld x = 42. Dit declareert altijd een globale variabele. Dit genereert een stricte JavaScript waarschuwing. Je zou deze manier niet moeten gebruiken.
  • Met het keyword let. Bijvoorbeeld let y = 13. Deze syntax kan worden gebruikt om een lokale blokvariabele te declareren. Zie ook Variable scope verderop.

Variabelen evalueren

Een door var or let gedeclareerde variabele zonder gespecificeerde initiële waarde heeft de waarde undefined.

Een poging om een niet-gedeclareerde variabele te gebruiken resulteert in een ReferenceError exceptie:

var a;
console.log("De waarde van a is " + a); // logs "De waarde van a is undefined"
console.log("De waarde van b is " + b); // throws ReferenceError exception

Je kunt undefined gebruiken om te bepalen of een variabele een waarde heeft. In de volgende code heeft de variabele input geen waarde toegewezen gekregen en het if statement evalueert naar true;

var input;
if(input === undefined){
  doeDit();
} else {
  doeDat();
}

De undefined waarde gedraagt zich als false in de context van een booleaanse waarde. Bijvoorbeeld, de vogende code voert de functie myFunction uit omdat het myArray element undefined is:

var myArray = [];
if (!myArray[0]) myFunction(); 

De undefined waarde converteert naar NaN als deze wordt gebruikt in numerike context.

var a;
a + 2;  // Evalueert naar NaN

A;s je een null variabele declareert, dan gedraagt deze zich als 0 in een numerike context en als false in een booleaanse context. Bijvoorbeeld:

var n = null;
console.log(n * 32); // Zal 0 tonen in de console

Variable bereik (scope)

Als je een variabele declareert buiten een functie, dan wordt dit een globale variabele genoemd, omdat deze beschikbaar is voor alle code in het document. Als je een variabele in een functie declareert, dan wordt dit een lokale variabele genoemd, want deze is alleen beschikbaar binnen die functie.

Voor ECMAScript 6 had JavaScript nog geen block statement scope. Een variabele gedeclareerd in een blok was lokaal voor de functie waarin het blok geplaatst is. De volgende code zal bijvoorbeeld 5 loggen, omdat het bereik van x de volledige functie waarin x is gedeclareerd, niet enkel het (in dit geval if statement) blok.

if (true) {
  var x = 5;
}
console.log(x);  // 5

Dit gedrag verandert wanneer de let declaratie werd geïntroduceerd in ECMAScript 6.

if (true) {
  let y = 5;
}
console.log(y);  // ReferenceError: y is niet gedefinieerd

Variable hoisting (variabele ophijsen)

Een andere ongebruikelijke eigenschap van variabelen in JavaScript is dat je kan refereren naar een variabele die pas later in de code wordt gedeclareerd, zonder een exceptie te krijgen. Dit concept staat bekend als hoisting (ophijsen); variabelen in JavaScript worden als het ware opgehesen naar het begin van de functie of statement. Echter, variabelen die opgehesen worden resulteren in een waarde undefined, ook als de variabele later wordt geïnitialiseerd.

/**
 * Voorbeeld 1
 */
console.log(x === undefined); // logs "true"
var x = 3;

/**
 * Voorbeeld 2
 */
// retourneert een waarde undefined
var myvar = "my value";
 
(function() {
  console.log(myvar); // undefined
  var myvar = "local value";
})();

Dit voorbeeld wordt hetzelfde geïnterpreteerd als:

/**
 * Voorbeeld 1
 */
var x;
console.log(x === undefined); // logs "true"
x = 3;
 
/**
 * Voorbeeld 2
 */
var myvar = "my value";
 
(function() {
  var myvar;
  console.log(myvar); // undefined
  myvar = "local value";
})();

Door hoisting zouden alle var statements in een functie zo dicht mogelijk aan het begin van de functie moeten worden gedeclareerd. Dit leidt tot een verbeterde duidelijkheid van de code.

Globale variabelen

Globale variabelen zijn in feite eigenschappen van het globale object. Op webpgina's is het globale object window, dus je kunt globale variabelen aanroepen met window.variable.

Zodoende is het ook mogelijk om globale variabelen die in een ander window of frame zijn gedeclareerd aan te roepen door de naam van het window of frame te specificeren. Bijvoorbeeld, als een variabele genaamd telefoonnummer is gedeclareerd in een document, dan kan deze variabele vanuit een frame worden aangeroepen met parent.telefoonnummer.

Constanten

Het is mogelijk om alleen-lezen constanten te declareren met het const keyword.

De syntax van een constante identifier is hetzelfde als voor een variabele identifier: de naam moet beginnen met een letter, underscore of dollarteken en kan alfabetische, numerieke of underscorekarakters bevatten.

const prefix = '212';

Een constante kan niet van waarde worden veranderd of opnieuw worden gedeclareerd tijdens het runnen van het script. Een constante moet worden geïnitialiseerd.

De scope (bereik) regels voor constanten zijn hetzelfde als voor let blokbereik variabelen. Als het const keyword wordt weggelaten, dan wordt aangenomen dat de identifier een variabele representeert.

Het is niet mogelijk om een constante te declareren met dezelfde naam als een functie of variabele in hetzelfde bereik. Bijvoorbeeld:

// DIT RESULTEERT IN EEN ERROR
function f() {};
const f = 5;

// DIT OOK
function f() {
  const g = 5;
  var g;

  //statements
}

Datastructuren en types

Datatypes

De meest recente ECMAScript standaarden definiëren zeven datatypes:

  • Zes datatypes zijn primitieven:
    • Boolean. true en false.
    • null. Een speciaal keyword voor het aangeven van een nullwaarde. Omdat JavaScript hoofdlettergevoelig is, is null niet hetzelfde als Null, NULL, en elke andere variant.
    • undefined. Een top-level eigenschap met een ongedefinieerde waarde.
    • Number. 42 of 3.14159.
    • String. "Hello World"
    • Symbol (nieuw in ECMAScript 6). Een datatype wiens instanties uniek en onveranderbaar zijn.
  • en Object

Ondanks dit kleine aantal datatypes, geven ze de mogelijkheid om zinvolle functies te schrijven voor applicaties. Objects en functions zijn de andere fundamentele elementen in de taal. Je kan objecten zien als benoemde containers voor waarden en functies als procedures die de applicatie kan uitvoeren.

Datatype conversie

JavaScript is een dynamic typed taal. Dat betekent dat het niet nodig is om een datatype op te geven bij het declareren van een variabele en dat datatypes automatisch worden geconverteerd tijdens het uitvoeren van een script. Een variabele kan bijvoorbeeld als volgt worden gedeclareerd:

var answer = 42;

en later kan dezelfde variabele een string toegewezen krijgen:

answer = "Thanks for all the fish...";

Omdat JavaScript dynamically typed is, leidt deze toewijzing niet tot een foutmelding.

In expressies waar numerieke en string waarden met de + operator worden gecombineerd, converteert JavaScript de numerieke waarde naar een string. Bijvoorbeeld:

x = "Het antwoord " + 42 // "Het antwoord is 42"
y = 42 + " is het antwoord" // "42 is het antwoord"

In statements met andere operatoren converteert JavaScript numerike waarden niet naar strings. Bijvoorbeeld±

"37" - 7 // 30
"37" + 7 // "377"

Strings naar Numbers converteren

In gevallen waarin een numerieke waarde in het geheugen wordt gerepresenteerd als een string, zijn er mogelijkheden voor conversie:

parseInt retourneert enkel gehele getallen. Het is aanbevolen om altijd een radix mee te geven aan parseInt. De radixparameter wordt gebruikt om te specificeren welk numeriek systeem moet worden gebruikt.

Een andere manier om getallen uit strings te extraheren is met de + (unaire plus) operator:

"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2   
// Note: de haakjes zijn toegevoegd voor de duidelijkheid, maar niet vereist.

Literalen

Je kunt literalen gebruiken om waarden te representeren in JavaScript. Dit zijn vaste waarden, geen variabelen, die letterlijk in het script staan.. Deze sectie beschrijft de volgende type literalen:

Array literalen

Een array literaal is een lijst van nul of meerdere expressies. Elke expressie representeert een array element omgeven door vierkante haakjes ([]).

Het volgende voorbeeld creëert een array koffies met drie elementen en een lengte van 3:

var koffies = ["Espresso", "Cappuccino", "Zwart"];

Note : Een array literaal is een soort object initialisator. Zie Using Object Initializers.

Als een array wordt gecreëerd met een literaal in een top-leven script, dan interpreteert JavaScript de array elke keer dat het de expressie die de array literaal bevat evalueert. Een literaal die gebruikt wordt in een functie wordt iedere keer dat de functie wordt aangeroepen opnieuw gecreëerd.

Array literalen zijn ook Array objecten. Zie Array en Indexed collections voor meer details over Array objecten.

Extra komma's in array literalen

Je hoeft niet alle elementen in een array literaal te specificeren. Als je twee komma's achter elkaar plaatst, dan wordt er op die plek in de array een undefined element toegevoegd. Bijvoorbeeld:

var kleuren = ["rood", , "groen"];

Deze array heeft twee elementen met waarden en 1 leeg element. (kleuren[0] is "rood", kleuren[1] is undefined, en kleuren[2] is "groen").

Als een komma aan het einde van een lijst elementen wordt geplaatst, dan wordt deze genegeerd. In het volgende voorbeeld is de lengte van de array 3. Er is geen mijnPlaatsen[3].

Note : Aan het einde geplaatste komma's kunnen fouten veroorzaken in oude versies van browsers. Het is beter om deze weg te laten.

var mijnPlaatsen = ['thuis', , 'school', ];

In het volgende voorbeeld is de lengte van de array 4 en mijnPlaatsen[0] en mijnPlaatsen[2] ontbreken.

var mijnPlaatsen = [ , 'home', , 'school'];

In het volgende voorbeeld is de lengte van de array 4 en mijnPlaatsen[1] enmijnPlaatsen[3] ontbreken. Alleen de laatste komma wordt genegeerd.

var mijnPlaatsen = ['home', , 'school', , ];

Het begrijpen van het gedrag van extra komma's is belangrijk voor het begrijpen van JavaScript als een programmeertaal. Echter, het expliciet benoemen van ontbrekende elementen met het keyword undefined verbetert de duidelijkheid en onderhoudbaarheid van de code.

Boolean literalen

Het Booleaanse type heeft twee literale waarden: true en false.

Verwar de primitieven Boolean waarden true en false niet met de true en false waarden van het Boolean object. Het Boolean object is een omhulsel voor het primitieve Boolean datatype. Zie Boolean voor meer informatie.

Integers

Integers kunnen worden uitgedrukt in decimaal (radix 10), hexadecimaal (radix 16), octaal (radix 8) en binair (radix 2).

  • Decimale integer literalen bestaan uit een rij van cijfers zonder 0 (nul) aan het begin.
  • Een 0 (nul) (of 0o of 0O) aan het begin van een integer literaal geeft aan dat de integer in het octale stelsel is uitgedrukt. Octale integers kunnen enkel bestaan uit de cijfers 0 tot en met 7.
  • 0x (of 0X) aan het begin geeft hexadecimale notatie aan. Hexadecimale integers kunnen bestaan uit de cijfers 0 tot en met 9 en de letters a tot en met F en A tot en met F.
  • 0b (of 0B) aan het begin geeft binarye notatie aan. Binaire integers kunnen bestaan uit de cijfers 0 en 1.

Enkele voorbeelden van Integer literalen zijn:

0, 117 en -345 (decimaal, radix 10)
015, 0001 en -0o77 (octaal, radix 8) 
0x1123, 0x00111 en -0xF1A7 (hexadecimaal, "hex" or radix 16)
0b11, 0b0011 en -0b11 (binair, radix 2)

Voor meer informatie, zie Numeric literals in the Lexical grammar reference.

Floating-point literalen

Een floating-point literaal kan bestaan uit de volgende onderdelen:

  • Een decimale integer eventueel voorafgegaan door een "+" of "-" teken),
  • Een decimaalscheiding punt ("."),
  • Een fractie (decimaal nummer),
  • Een exponent.

Het exponent gedeelte is een "e" of "E" gevolgd door een integer, welke kan worden voorafgegaan door een "+" of "-". Een floating point literaal moet minstens 1 cijfer hebben en een decimaalscheiding punt óf een "e" (of"E").

Meer beknopt, de syntax is:

[(+|-)][cijfers][.cijfers][(E|e)[(+|-)]cijfers]

Bijvoorbeeld:

3.1415926
-.123456789
-3.1E+12
.1e-23

Object literalen

Een object literaal is een lijst van nul of meerdere paren van namen en waarden van eigenschappen, ingesloten door accolades ({}). Een object literaal kan niet worden gebruikt aan het begin van een statement. Dit zou leiden tot een foutmelding of gedraagt zich niet zoals verwacht, omdat de { zal worden geïnterpreteerd als het begin van een blok.

De volgende code is een voorbeeld van een object literaal. Het eerste element van het auto object definieert de eigenschap mijnAuto en wijst de string "VW" toe; de tweede eigenschap krijgt het resultaat van de aanroep van functie autoTypes("Honda") toegewezen; het derde element, de special eigenschap, krijgt een bestaande variabele toegewezen (sales).

var sales = "Toyota";

function carTypes(name) {
  if (name === "Honda") {
    return name;
  } else {
    return "Sorry, we verkopen geen " + name + ".";
  }
}

var auto = { mijnAuto: "VW", getAuto: autoTypes("Honda"),
             special: sales };

console.log(auto.mijnAuto); // VW
console.log(auto.getAuto);  // Honda
console.log(auto.special);  // Toyota 

Namen van objecteigenschappen kunnen ook numerieke literalen zijn. Waarden van objecteigenschappen kunnen ook weer objecten zijn (geneste objecten). Het volgende voorbeeld gebruikt deze mogelijkheden:

var auto = { veelAutos: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };

console.log(auto.veelAutos.b); // Jeep
console.log(auto[7]); // Mazda

De namen van objecteigenschappen kunnen elke string zijn, ook de lege string (""). Als de naam van een eigenschap geen geldige JavaScript identifier of getal is, moet deze worden ingesloten door quotes (als een string). Deze eigenschappen kunnen dan niet worden aangeroepen als een punt (.) eigenschap, maar kunnen wel worden opgevraagd en waarden toegekend krijgen met de array notatie ([]). Zie voorbeeld:

var aparteEigenschapNamen = {
  "": "Een lege string",
  "!": "Bang!"
}
console.log(aparteEigenschapNamen."");   // SyntaxError: Unexpected string
console.log(aparteEigenschapNamen[""]);  // Een lege string
console.log(aparteEigenschapNamen.!);    // SyntaxError: Unexpected token !
console.log(aparteEigenschapNamen["!"]); // Bang!

Object literalen zijn uitgebreid in ES2015. Het is hierdoor mogelijk om het prototype in te stellen tijdens constructie, foo: foo constructies in te korten, methodes te definiëren, super aanroepen te doen en dynamische eigenschapnamen te berekenen. Dit brengt object literalen en klasse declaratie dichter bij elkaar.

var obj = {
    // __proto__
    __proto__: theProtoObj,
    // Shorthand for ‘handler: handler’
    handler,
    // Methods
    toString() {
     // Super calls
     return "d " + super.toString();
    },
    // Computed (dynamic) property names
    [ 'prop_' + (() => 42)() ]: 42
};

Let op:

var foo = {a: "alpha", 2: "two"};
console.log(foo.a);    // alpha
console.log(foo[2]);   // two
//console.log(foo.2);  // Error: missing ) after argument list
//console.log(foo[a]); // Error: a is not defined
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two

RegExp literalen

Een regex literaal is een patron ingesloten door slashes (/). Het volgende voorbeeld toont een regex literaal:

var re = /ab+c/;

String literalen

Een string literaal is een rij van nul of meerdere karakters ingesloten door dubbele (") of enkele (') quotes. Het quoteteken voor de string moet hetzelfde type quote zijn als de quote aan het einde. Voorbeelden van String literalen:

"foo"
'bar'
"1234"
"een regel \n nog een regel"
"Henk's kat"

Je kunt elke methode van het String object aanroepen op een String literaal. JavaScript converteert de string literaal automatisch naar een tijdelijk String object en roept dan de methode aan. Daarna wordt het tijdelijke String object genegeerd. De String.length eigenschap kan ook worden aangeroepen op string literalen.

// Print het aantal karakters in de string.
console.log("Henk zijn kat".length) // 13

In ES2015 zijn template literalen ook beschikbaar. Template strings bieden syntactische sugar voor het construeren van strings. Dit lijkt op string interpolation zoals in onder andere Perl en Python. Aan een string kan een tag worden toegevoegd voor het invoegen van bijvoorbeeld variabelen op plekken in de string. Deze methode vermijdt injectie-aanvallen en de benodigdheid van datastructuren voor het representeren van variabele strings.

// Simpele string literaal
`In JavaScript is '\n' een new-line karakter.`

// Multiline strings
`In JavaScript mag
 dit niet.`

// String interpolation
var naam = "Bob", wanneer = "vandaag";
`Hallo ${naam}, hoe gaat het ${wanneer}?`

// Construct an HTTP request prefix is used to interpret the replacements and construction.
POST `http://foo.org/bar?a=${a}&b=${b}
     Content-Type: application/json
     X-Credentials: ${credentials}
     { "foo": ${foo},
       "bar": ${bar}}`(myOnReadyStateChangeHandler);

Het gebruik van string literalen is aanbevolen, tenzij je specifiek het String object nodig hebt.. Zie String voor details over String objecten.

Gebruik van speciale karakters in strings

Naast gewone karakters kunnen ook speciale karakters worden gebruikt in strings, zoals in het volgende voorbeeld:

"een regel \n nog een regel"

De volgende tabel toont de speciale karakters die in JavaScript strings kunnen worden gebruikt.

Table: JavaScript speciale karakters
Karakter Betekenis
\0 Null Byte
\b Backspace
\f Form feed (nieuwe pagina)
\n New line (nieuwe regel)
\r Carriage return (naar begin van de regel)
\t Tab
\v Verticale tab
\' Apostrof of enkel aanhalingsteken
\" Dubbel aanhalingsteken
\\ Backslash karakter
\XXX

Het karakter met de Latijn-1 encodering gespecificeerd door tot 3 octale cijfers XXX tussen 0 en 377. Bijvoorbeeld \251 is de octale code voor het copyrightsymbool.

\xXX

Het karakter met de Latijn-1 encodering gespecificeerd door de hexadecimale cijfers XX tussen 00 en FF. Bijvoorbeeld \xA9 is de hexadecimale code voor het copyrightsymbool.

\uXXXX

Het Unicode-karakter gespecificeerd door de 4 hexadecimale cijfers XXXX. Bijvoorbeeld \u00A9 is de Unicode voor het copyright symbook. Zie Unicode escape sequences.

\u{XXXXX} Unicode code point escapes. Bijvoorbeeld \u{2F804} is hetzelfde als de eencoudige Unicode escapes \uD87E\uDC04.

Escapekarakters

Voor karakters die niet in de tabel staan wordt de voorafgaande backslash genegeerd, maar dit gebruik is verouderd en moet worden ontweken.

Je kunt een quoteteken invoegen in een string door voor het teken een backslash (\) toe te voegen. Dit staat bekend als escaping van het quoteteken. Bijvoorbeeld:

var quote = "Hij las \"The Cremation of Sam McGee\" door R.W. Service.";
console.log(quote);

Het resultaat hiervan zou zijn:

Hij las "The Cremation of Sam McGee" door R.W. Service.

Om een backslash in de string toe te voegen, moet het backslash tegen worden geëscaped. Bijvoorbeeld, om het bestandspad c:\temp in een string voor te stellen staat in JavaScript het volgende:

var home = "c:\\temp";

Het is ook mogelijk om nieuwe regels in de code te escapen. De backslash en nieuwe regel worden beide niet in de string opgenomen.

var str = "deze string \
is verspreid \
over meerdere\
regels."
console.log(str);
// deze string is verspreid over meerdere regels.

Alhoewel JavaScript geen "heredoc" syntax heeft, kan je wel een newline karakter samen met een escape karakter gebruiken, zoals in het volgende voorbeeld:

var poem = 
"Roses are red,\n\
Violets are blue.\n\
I'm schizophrenic,\n\
And so am I."

Meer informatie

Dit hoofdstuk focust op de basis syntax voor declaraties en types. Om meer te leren over de JavaScript programmeertaal constructies, zie de volgende hoofdstukken in de guide:

In het volgende hoofdstuk nemen we een kijkje in de control flow constructies en error handling

Documentlabels en -medewerkers

Labels: 
 Aan deze pagina hebben bijgedragen: maartentbm
 Laatst bijgewerkt door: maartentbm,