JavaScript voor beginners: Strings & Arrays
In de vorige aflevering hebben we het gehad over de JavaScript-operators. Ook hebben we kort gekeken naar enkele aanvullende bronnen met informatie over JavaScript.In deze aflevering zullen we zien hoe we in JavaScript tekenreeksen of "strings" gebruiken voor het manipuleren van tekstuele informatie. Ook het aan strings verwante onderwerp "arrays" komt aan de orde.
Strings
In het verleden dacht men bij de term "programmeren" direct aan het uitvoeren van ingewikkelde berekeningen. Denk maar aan een vroege programmeertaal als FORTRAN: de naam is afgeleid van FORmula TRANslator, dus een taal voor het omzetten van wiskundige formules naar een computeromgeving. Tegenwoordig weten we dat computers ook heel goed gebruikt kunnen worden voor het manipuleren van tekenreeksen ofwel "strings".Strings behoren tot de ingebouwde gegevenstypen van JavaScript. Een string is een tekenreeks waar enkele of dubbele aanhalingstekens omheen staan, bijvoorbeeld: "Help!" of: 'Help!' Fout zou echter zijn: "Help!' of: 'Help!", want het type van het aanhalingsteken openen moet gelijk zijn aan dat van het aanhalingsteken sluiten. De string kan zelf ook aanhalingstekens bevatten; in zo'n geval gebruiken we afwisselend dubbele en enkele aanhalingstekens, bijvoorbeeld: "'Help!' riep de badgast" of: '"Help!" riep de badgast'.
Willen we in de string een enkel aanhalingsteken gebruiken, dan moeten we daarvoor een zogenaamde escape sequence gebruiken. Het aanhalingsteken wordt in zo'n geval voorafgegaan door een backslash ("\"). De string '"Help, 'k verdrink!" riep de badgast' geven we derhalve in JavaScript weer door middel van: '"Help, \'k verdrink!" riep de badgast'. Iets soortgelijks geldt indien we een dubbel aanhalingsteken in onze string willen opnemen: daarvoor gebruiken we dan \".
Ook voor enkele andere speciale tekens gebruiken we een escape sequence. Zo kunnen we bijvoorbeeld aangeven dat de tekst van een JavaScript-alert over meerdere regels moet worden verdeeld, door een line feed- of newline-teken in de string op te nemen. Daartoe gebruiken we de escape sequence \n, dus bijvoorbeeld: "Twee dingen zijn essentieel voor het opbouwen van een machtspositie. \n 1. Vertel nooit alles." De tweede zin van het voorbeeld komt hiermee op een regel onder de eerste te staan.
Met \t geven we een "tabstop" aan; hiermee kunnen we bijvoorbeeld tabellen maken waarvan de teksten in verschillende kolommen netjes onder elkaar staan. Als we bijvoorbeeld schrijven: alert('kolom1 \t kolom2 \t kolom3 \na \t b \t c'), dan komt de a netjes onder de k van kolom1, de b onder de k van kolom2, en de c onder de k van kolom3.
Dat geldt althans voor een JavaScript-alert. Als we echter proberen om een HTML-document op deze wijze op te maken --m.b.v.: document.write('kolom1 \t kolom2 \t kolom3 \na \t b \t c')--, dan heeft dat normalerwijze niet het beoogde effect. Door ons script worden namelijk wel tabstops en new line-tekens aangemaakt, maar die worden in HTML behandeld als "white noise" en dus bij het tonen van de pagina door de browser genegeerd! Als we echter met behulp van JavaScript onze string laten genereren tussen de HTML-tags <PRE> en </PRE> (die aangeven dat het om "gepreformatteerde" tekst gaat), dan krijgen we wel het beoogde resultaat. We moeten er dan wel voor zorgen dat de <PRE>-tags om de <SCRIPT>-tags heen staan, en niet andersom. In het laatste geval zouden de <PRE>-tags namelijk worden behandeld als JavaScript-opdrachten i.p.v. HTML-tags, en een foutmelding veroorzaken.
De laatste escape sequence die we hier zullen bekijken, heeft betrekking op de backslash zelf. Doordat het backslash-teken wordt gebruikt als escape character, om aan te geven dat het volgende teken een speciale betekenis heeft, kunnen we het niet zomaar opnemen in een string. In plaats daarvan gebruiken we een dubbele backslash, dus bijvoorbeeld: "U vindt het bestand in directory C:\\TEST", waarmee we dan verwijzen naar C:\TEST.
Manipuleren
Als we strings alleen maar zouden kunnen tonen, dan waren we er snel over uitgepraat. We hebben echter in JavaScript verschillende middelen tot onze beschikking om er iets "nuttigs" mee te doen.Allereerst kunnen we strings samenvoegen of "concateneren"; daartoe gebruiken we de operator "+". Als stringvariabele A de string "Het is lente." bevat, dan kunnen we schrijven: B = "Om te beginnen bij het begin: " + A waardoor stringvariabele B als waarde krijgt: "Om te beginnen bij het begin: Het is lente."
We noemden strings eerder één van de ingebouwde gegevenstypen van JavaScript. Als we heel precies willen zijn, dan moeten we eigenlijk zeggen dat strings een van de ingebouwde (of "intrinsieke") objecttypen van JavaScript zijn. Objecten hebben, zoals we in de volgende aflevering zullen zien, een aantal eigenschappen of "properties" en een aantal "methods". In het geval van strings is er slechts één property die de moeite waard is, te weten: length. Hiermee kunnen we bepalen hoeveel tekens een string bevat. Als X de string "Laura" is, dan geldt dat X.length de waarde 5 heeft; is X een lege string (""), dan heeft X.length de waarde 0.
Interessanter dan die property zijn de verschillende methods van het string-object: daarmee kunnen we onze strings namelijk manipuleren. Als string X de waarde "Test" bevat, dan kunnen we bijvoorbeeld schrijven: Y = X.toUpperCase(), en daardoor krijgt Y de waarde "TEST". Op vergelijkbare wijze geeft Z = X.toLowerCase() aan Z de waarde "test". (Let op de precieze schrijfwijze met hoofd- en kleine letters en met haakjes aan het eind, anders krijg je een foutmelding!) Deze methoden werken niet alleen bij variabelen maar ook bij constanten; we kunnen dus bijvoorbeeld ook schrijven: document.write("Test".toLowerCase()). Deze twee methoden werken alleen bij de gewone letters van ons alfabet, dus niet bij tekens met bijvoorbeeld een umlaut of een accent.
Er zijn verschillende methoden waarmee we de weergave van strings kunnen beïnvloeden. Een voorbeeld daarvan is "bold". Als we schrijven: X = "test".bold(), dan krijgt X daarmee de waarde "<B>test</B>"; het woord "test" zal daardoor vet worden weergegeven indien X door de browser wordt getoond. Soortgelijke methoden zijn bijvoorbeeld "big", "blink", "fontcolor", "fontsize" en "sup": al deze methoden zetten de overeenkomstige HTML-tags rondom de string en beïnvloeden zo de weergave ervan in de browser.
Met de methode "charAt" kunnen we individuele tekens van de string benaderen. We moeten ons daarbij wel realiseren dat de telling begint bij nul en niet bij een. Om het eerste teken van string X te benaderen, schrijven we dus: X.charAt(0); het laatste teken van de string benaderen we met X.charAt(Y), waarbij geldt: Y = X.length - 1. (N.B.: bij "length" gebruiken we geen haakjes aan het eind, omdat het een property is en geen method!) Hiermee kunnen we bijvoorbeeld controleren wat we hiervoor hebben beweerd over de werking van bold. Als we schrijven: document.write("Test".bold().charAt(1)), dan wordt het tweede teken van de string getoond; omdat "bold()" <B> en </B> rondom de string heeft gezet, krijgen we een "B" te zien en dus niet de "e" van Test!
We kunnen ook onderdelen van de string benaderen die meer dan een enkel teken bevatten; hiertoe gebruiken we "substring". Deze methode heeft een verplichte parameter (de beginpositie) en een optionele (merkwaardig genoeg het teken NA de eindpositie). Als X bijvoorbeeld de waarde "Dit is een test" bevat, dan heeft X.substring(7,10) de waarde "een" (de tekens op positie 7 tot en met 9), en X.substring(7) de waarde "een test". Als we de optionele parameter achterwege laten, krijgen we dus alles vanaf de beginpositie tot aan het einde van de string.
Zoeken en vinden
Vaak is het interessant om te weten of een bepaalde string voorkomt in een grotere string. We kunnen dat nagaan met de methoden indexOf en lastIndexOf (let op de spelling!). Heeft string X de waarde "'Mijn lief, mijn lief, mijn lief', zo sprak mijn lief mij toe", dan heeft X.indexOf("lief") de waarde 6: "lief" komt namelijk inderdaad voor binnen string X, en wel (de eerste keer) vanaf positie 6. Komt de gezochte string niet voor, zoals in X.indexOf("liefde"), dan krijgen we als resultaat -1. Ook hier kunnen we een optionele parameter gebruiken: schrijven we X.indexOf("lief",7), dan wordt niet gezocht vanaf positie 0 (het begin van de string) maar vanaf positie 7, en het resultaat is in dat geval 17.Iets soortgelijks geldt voor de methode lastIndexOf, alleen wordt daar niet gezocht naar de eerste maar naar de laatste keer dat de substring voorkomt; er wordt dus gezocht vanaf het einde van de string. In ons voorbeeld geldt: X.lastIndexOf("lief") heeft de waarde 49; X.lastIndexOf("liefde") heeft de waarde -1 en X.lastIndexOf("lief",10) heeft de waarde 6.
Overigens kent JavaScript voor het zoeken in strings ook een methode search. Deze maakt gebruik van zogenaamde "regelmatige uitdrukkingen" (regular expressions), net als de methoden match, replace, split, test en exec waarmee in strings kan worden gezocht, vervangen en verwijderd. Regular expressions en de bijbehorende methoden worden echter pas ondersteund vanaf JavaScript versie 1.2, en we zullen er hier niet verder op in gaan.
Arrays
We hebben gezien dat we strings als geheel kunnen benaderen maar ook als een "verzameling" van individuele elementen (de losse letters waaruit de string bestaat). In dat opzicht lijken strings op "arrays": ook daar is sprake van een object dat individuele elementen bevat die onafhankelijk van elkaar kunnen worden benaderd. (Bij de taal Pascal zien we die verwantschap goed terug: wat in JavaScript een string heet, heette in Pascal oorspronkelijk een "array of char[acters]", dus een array bestaande uit lettertekens.)Arrays behoren, net als strings, tot de ingebouwde objecttypen van JavaScript en hebben, naast de property length die het aantal elementen in een array aangeeft, een aantal methoden waarmee de individuele elementen kunnen worden gemanipuleerd (bijvoorbeeld: samengevoegd of gesorteerd).
Om arrays te kunnen gebruiken, moeten we ze eerst expliciet creëren met behulp van de "constructor" new. We kunnen bijvoorbeeld schrijven: X = new Array() en zo een array aanmaken die nog geen elementen bevat. Vervolgens kunnen we enkele elementen aan de array toevoegen, bijvoorbeeld: X[0] = "aap"; X[1] = "noot"; X[2] = "mies". We verwijzen dus naar een element van een array door middel van zijn "index", geplaatst tussen vierkante haken; en ook bij arrays beginnen we te tellen bij nul.
Er bestaat echter een eenvoudiger manier om het array uit het voorbeeld aan te maken en te vullen. We kunnen namelijk ook schrijven: X = new Array("aap", "noot", "mies"). De elementen van het array hoeven overigens niet altijd strings te zijn, en we mogen ook elementen van verschillende typen door elkaar gebruiken, bijvoorbeeld: X = new Array("aap", 3.1415, true).
Het is zelfs mogelijk dat een element van een array zelf een array bevat, bijvoorbeeld: X[2] = new Array("a","b","c"); op deze manier ontstaat een "multidimensionale" (in dit geval: tweedimensionale) array. Om te verwijzen naar een individueel element van zo'n array schrijven we bijvoorbeeld: Y = X[2][1], waardoor Y de waarde "b" krijgt. Schrijven we: document.write(X[2]), dan wordt het hele array X[2] getoond, dus: "a,b,c". Op soortgelijke wijze kunnen we de inhoud van een array in een keer toekennen aan een ander array: Z = X[2].
We kunnen zelfs schrijven: document.write(X), met als resultaat: "aap,3.1415,a,b,c"; het multidimensionale array wordt in zo'n geval "opengevouwen" tot een eendimensionaal array.
Behalve de expliciet gecreëerde arrays uit onze voorbeelden, kent JavaScript ook arrays die als het ware "impliciet" ontstaan bij het aanmaken van onze HTML-pagina's. Een voorbeeld hiervan is "links": dit array (dat zelf een property is van het object "document") bevat de links op onze pagina, in de volgorde waarin ze op de pagina voorkomen. Dit array "ziet" overigens alleen links die "reeds eerder" in de HTML zijn opgenomen. Bevat onze pagina twee links, een verwijzing naar document.links.length (het aantal elementen in dit array, dus: het aantal links op de pagina), en vervolgens een derde link, dan geeft document.links.length de waarde 2 en niet 3, omdat de laatste link nog niet "bekend" was op het moment van de verwijzing. Zoals we in een latere aflevering nog zullen zien, behandelt JavaScript niet alleen "links" (en het verwante "anchors"), maar ook de verschillende elementen van een formulier (<FORM>) als (impliciete) arrays.
Methoden
Behalve de ene property "length" hebben arrays, zoals gezegd, een aantal methoden waarmee de individuele elementen kunnen worden gemanipuleerd.Met reverse kunnen we een array omdraaien zodat het laatste element het eerste wordt en andersom. Als geldt: X = new Array("a","b","c"), dan geeft document.write(X.reverse()) het resultaat "c,b,a".
Met de methode sort kunnen we de elementen van het array alfabetisch sorteren: als geldt X = new Array("aap","noot","mies"), dan heeft X = X.sort() tot gevolg dat X[0] = "aap", X[1]="mies" en X[2]="noot". Geldt X = new Array(100,2,3,10,20,1), dan geeft document.write(X.sort()) het resultaat "1,10,100,2,20,3"!
De elementen van een array kunnen worden samengevoegd tot een string met behulp van de methode join: als geldt X = new Array("aap","noot","mies"), dan krijgt myString met myString = X.join(":+") de waarde "aap:+noot:+mies". Hierbij is de "separator" (de tekens ":+" in het voorbeeld) optioneel; laten we die weg, dan krijgt myString de waarde "aap,noot,mies".
Conclusie
We hebben het deze keer gehad over strings en arrays, twee "ingebouwde" objecttypen van JavaScript. In de volgende aflevering komen de eigenschappen en methoden van enkele andere ingebouwde objecten als Date en Math ter sprake. Daarnaast zullen we het hebben over objecten die je zelf definieert, en over zogenaamde browser-objecten.
