Website van Eduard de Jong

JavaScript-tutorial,
door Eduard de Jong



Inhoudsopgave


Inleiding

Basis:
 - HTML, CSS en JavaScript.
 - programmeertaal, scripttaal, opmaaktaal.
 - de plaatsing van het script in het document
   (bijv. achter javascript:, tussen <script>-tags, in een event-handler).
 - extern JavaScript-bestand.
 - commentaar.
 - veelgebruikte opdrachten
   (bijv. document.write(), window.alert(), window.open(),
   window.status, window.location).
 - hoofdletter- en leestekengevoeligheid.

Events:
 - event-handlers (bijv. onclick, onmouseover).
 - event-object.

Variabelen:
 - soorten datatypen.
 - aanroep.
 - definiëring (met =).
 - declaratie (met var).
 - globaal en lokaal.

Functies:
 - aanroep (met haakjes ( )).
 - declaratie (met function en met haakjes ( )).
 - definiëring (tussen accolades { }).
 - parameters (argumenten).
 - waarde teruggeven (met return).
 - toekennen aan variabele.

Statements:
 - if en else.
 - switch, case en default (en break).
 - with.
 - for.
 - while (en do).
 - recursie.

Operators:
 - =
 - + - * / %
 - ++ --
 - += -= *= /= %=
 - == != ! < > <= >= && ||
 - verschil tussen = en ==.
 - ? :
 - << >> >>> ~ | & ^
 - delete  void  typeof  instanceof  in  new  this.
 - voorrangsregels.

Strings:
 - definiëring (new String() of "").
 - aanhalingstekens (" en ').
 - \ (bijv. \\, \n, \t, \", \').
 - indexOf(), lastIndexOf(), charAt(), substring(), length en split(), etc.
 - toLowerCase(), toUpperCase(), bold(), italics(), fontsize(), etc.

Arrays:
 - definiëring (new Array() of []).
 - nummering tussen vierkante haakjes [].
 - nummering via parameters.
 - datatypen in een array.
 - length en join().

Objecten:
 - objectgebaseerde taal.
 - objecten en constructors.
 - variabelen/eigenschappen en functies/methoden.
 - manieren om objecten te maken.
 - objecten in objecten.
 - aanroep van eigenschappen en methoden.
 - objecttypen voor datatypen
   (Object(), Array(), String(), Number(), Boolean(), Function()).

Browserobjecten:
 - window-object.
    - frames (bijv. top, parent, self, window.frames).
    - popupvensters (window.open()).
    - location-object.
    - history-object.
    - navigator-object.
    - document-object.
       - document.title, document.bgColor, document.fgColor, etc.
       - document.body.
       - eigenschappen van HTML-elementen.
         (bijv. name, id, innerHTML, innerText).
       - HTML-elementen aanroepen.
       - document.all en document.getElementById(), etc.
       - formulieren.
       - methoden in formulieren
         (bijv, focus(), select(), submit(), reset()).
       - CSS en het style-object.
       - layers.

Overige objecten, objecttypen en functies:
 - setTimeout(), setInterval(), clearTimeout(), clearInterval().
 - eval().
 - parseInt() en parseFloat().
 - escape() en unescape().
 - Image().
 - Date().
 - Math.

Cookies:
 - document.cookie.
 - tijdelijkheid van een cookie.
 - beschikbaarheid van een cookie.
 - beveiliging van een cookie.

ActiveX:
 - ActiveXObject().
 - FileSystemObject.
 - Windows Script Host.
 - Server-side JavaScript.

VBScript:
 - syntaxis.
 - ActiveX.
 - Communicatie tussen JavaScript en VBScript.
 - Visual Basic (VB).

Java:
 - compilatie en uitvoering.
 - objectgeoriënteerd (OO).
 - declaraties.
 - globaal en lokaal.
 - klassen.
 - instantiëring.
 - overerving.
 - afscherming.
 - polymorfisme.
 - toepassingen.
 - applets.
 - API
 - Java in JavaScript.

Slotwoord



Inleiding

Welkom op deze tutorial over JavaScript. In deze tutorial leg ik op een overzichtelijke manier uit hoe de taal JavaScript in elkaar zit. Hierbij begin ik met een uitleg over enkele belangrijke basisdingen van de taal die nodig zijn om goed te kunnen beginnen met de tutorial. Later in de tutorial ga ik het over wat ingewikkeldere zaken hebben, zoals statements, operators, Strings en Arrays. En nog verder in tutorial, als we echt wat verder gevorderd zijn met JavaScript, heb ik het over de structuur van objecten, methoden en eigenschappen, om zo een echt goed beeld te geven van hoe de taal in elkaar zit. En dan leg ik ook uit hoe we zelf objecten kunnen maken. Vervolgens vertel ik wélke objecten en funties er allemaal bestaan in JavaScript en waarvoor ze handig zijn. Hierna noem ik nog een aantal andere dingen van JavaScript die erg handig kunnen zijn, maar die ook problemen kunnen geven met veiligheid en privacy, zoals cookies en ActiveX. En ten slotte heb ik het nog over andere talen die op JavaScript lijken, maar toch anders zijn, zoals VBScript en Java. De meeste tutorials bespreken die verschillen al aan het begin, maar het is beter om de verschillen pas aan het eind te bespreken, als ik helemaal uitgelegd heb hoe de taal JavaScript in elkaar zit. Verschillen met andere talen zijn dan beter te snappen.

Ik hoop dat iedereen die deze tutorial gebruikt er veel aan zal hebben en ik wens hem of haar alvast veel succes met deze tutorial en met programmeren in JavaScript.

Terug naar Inhoudsopgave


Basis

JavaScript wordt gebruikt om websites dynamischer en functioneler te maken, om ze minder statisch te maken.
Websites worden voor een groot deel geschreven in HTML, en tegenwoordig ook wel eens in XML. Maar met alleen zo'n taal hebben we nog geen echt flitsende site. Het is dan allemaal nog erg statisch en weinig vormrijk. Daarom zijn de talen CSS en JavaScript ontworpen: CSS (Cascading Style Sheets) om vooral meer opmaak en een vormrijker uiterlijk aan een site te geven, en JavaScript om vooral meer gebeurtenissen en beweging op een site te brengen en om controle- en rekenopdrachten uit te voeren op een site.
CSS en JavaScript kunnen echter niet apart gebruikt worden om een site te bouwen. De basis van de site, de opbouw, daarin blijft namelijk nog altijd HTML (of XML) nodig. De combinatie van HTML, CSS en JavaScript, die in de praktijk dus altijd wordt toegepast op een goede website, die wordt Dynamisch HTML genoemd, afgekort DHTML.
Omdat het gebruik HTML of XML dus zeer essentieel is op een website, is het belangrijk eerst goed HTML te leren voordat je met JavaScript begint (voor XML moet je ook HTML kunnen). Dit geldt ook voor server-side talen als PHP en ASP. In deze JavaScript-tutorial ga ik er dus van uit dat je HTML kunt. Wanneer je geen HTML-kennis hebt is het niet verstandig om al aan deze tutorial te beginnen, en zou ik eerst een goede HTML-tutorial gaan doen. Verder is het ook handig om enige CSS-kennis te hebben.

JavaScript is een scripttaal. Dat houd vooral in dat het een kleine programmeertaal is die geschikt is voor het gebruik in websites en dat het een programmeertaal is die niet gecompileerd moet worden voordat deze uitgevoerd kan worden. Compileren van een scripttaal gebeurt namelijk tijdens het lezen en uitvoeren van het script door de browser. Compileren is het omzetten van een voor de mens leesbare, maar voor de computer onbegrijpelijke taal, in een machinetaal die voor de computer begrijpelijk is, maar voor de mens niet meer leesbaar is. Bij een echte programmeertaal moet, in tegenstelling tot een scripttaal, de code die je geschreven hebt (de source, de broncode) eerst worden gecompileerd voordat deze uitgevoerd kan worden. De gecompileerde code wordt dan gegenereerd in een nieuw bestand met een andere extensie dan de source. Een belangrijk voorbeeld van een echte programmeertaal is de taal Java. De broncode van je programma schrijf je in een tekstbestand met de extensie .java. De gecompileerde, dus uitvoerbare versie van je programma wordt in een bestand met de extensie .class gegenereerd. Voor het compileren van een programmeertaal heb je een speciaal programma, een compiler, nodig. Bij Java is dat het programma "javac".
HTML (en ook XML) is geen programmeertaal en ook geen scripttaal. Het is een opmaaktaal (markup-language). Het is uitsluitend een taal waarin je de opbouw en de opmaak van je document aangeeft. Enige uitvoerende opdrachten en berekeningen komen niet voor in deze taal. In JavaScript wel.

JavaScript kan op verschillende plaatsen in een pagina worden gezet. Dat is voor een groot deel tussen <script>-tags. Maar ook op andere manieren kan JavaScript worden verwerkt in een pagina. Bijvoorbeeld in een link. Dit wordt dan bijvoorbeeld gedaan met javascript: of met een event-handler. Hier een voorbeeld van een script met javascript: in een link:
Klik

En hier heb ik een voorbeeld van een script in een event-handler onclick die in een link staat:
Klik

Beide links tonen een dialoogvenster met daarin de tekst "Hello world!", wanneer je er op klikt. Klikken met de muis is een voorbeeld van een event. Het script reageert dus op een event. En dat is waar event-handlers dus voor zorgen. Meer over events vertel ik in het volgende hoofdstuk Events. Het is zelfs mogelijk vrij grote JavaScript opdrachten in een link te stoppen:
Klik

Misschien is dit script wat te ingewikkeld om meteen te snappen, maar later in deze tutorial zul je dit soort opdrachten beter begrijpen. In ieder geval is het door JavaScript dus mogelijk veel te doen met alleen al een link. Kort gezegd gaat het in de link om de opdracht
window.open().document.write(), die een nieuw venster opent en daar tekst en HTML in zet.
Het voordeel van JavaScript tussen script-tags is dat het overzichtelijk is. Dit gaat als volgt:

<script language="JavaScript" type="text/javascript">
<!--
(Hier komt het script)
//-->
</script>

Het gebruik van het language-attribuut en het type-attribuut is een beetje dubbel, maar het is een goede gewoonte om het te doe aangezien de strengheid hiermee misschien verschilt per browser. Het gebruik van HTML-commentaar (<!-- en -->) is erg aan te raden om dit als gewoonte te doen. Dit is om verschillende redenen. Ten eerste kunnen browsers, vooral oudere versies, problemen geven met bepaalde tekens die in JavaScript worden gebruikt, vooral met < en >, omdat deze tekens al gebruikt worden bij HTML. Het kan dus zijn dat je browser HTML-tags denkt te zien in het JavaScript. Als dit gebeurd ontstaan er gauw errors. Maar de grootste fout kan ontstaan bij het gebruik van script-tags binnen een JavaScript. Hier heb ik een voorbeeld:
Op zich lijkt dit script correct te zijn. Maar toch ontstaat er een fout: de JavaScript-syntaxis is goed, maar door het gebruik van </script> binnen de document.write()-opendracht denkt je browser dat het script-blok op die plaats afgesloten wordt, en gaat de rest van het script dus gewoon als normale tekst en HTML lezen. Daardoor zal er dit in je browser te zien zijn:

");

De rest van de code achter de </script>-tag is HTML en zal dus niet worden weergegeven in de browser. Alleen "); is geen HTML. En verder ontstaat er nu ook een JavaScript-syntax-error, omdat het JavaScript nu dus afgekapt is. Een oplossing van het probleem is dus het gebruik van HTML-commentaar:
Dit script werkt foutloos, want alles wat tussen HTML-commentaar staat wordt niet direct als HTML herkend.
De plaatsing van script-tags in een broncode maakt in principe niet uit. Een script kan in de head gezet worden en in de body. Maar het kan ook ergens anders staan, direct tussen de <html>-tags. Voor zover deze tags nog nodig zijn. Moderne browsers kunnen ook een pagina zonder <html>-tags vaak correct weergeven.
De inhoud van een script kan echter wel bepalend zijn voor de plaatsing in de code. Namelijk wanneer de uitvoering van JavaScript plaatsvindt voordat de pagina helemaal geladen is. Maar als een script pas uitgevoerd word nadat de hele pagina geladen is (dit kan met de event-handler onload), dan maakt het niet uit waar het script staat. Hoe het precies zit met dit wachten tot de pagina geladen is leg ik later in de tutorial nog uit.
Je kunt javascript: gebruiken als doel van een link, in plaats van een URL, om een script uit te voeren. Je kunt dit echter ook zelf in de adresbalk typen om een stukje JavaScript uit te voeren. Dit kan bijvoorbeeld handig zijn om even snel een scriptje te testen. Een voorbeeld:
Kopiër het en plak het script in de adres balk en je zult een dialoogvenster zien met "Hello world!".

In plaats van een JavaScript te typen tussen script-tags, is het ook mogelijk een extern JavaScript aan te roepen met script-tags. Zo'n script-bestand geven we de extensie js. In een JS-bestand plaatsen we alleen JavaScript en HTML-commentaar, geen script-tags. De aanroep gaat zo:

<script language="JavaScript" type="text/javascript" src="script.js"></script>

Met het src-attribuut wordt hier een bestand "script.js" aangeroepen. Het script in dat bestand wordt uitgevoerd alsof het echt tussen de script tags staat. Voor de plaats in de broncode waar je deze script-tags zet geldt dus hetzelfde als bij script-tags met echt een script ertussen.

Het is in een JavaScript niet zomaar mogelijk om gewone tekst te typen zonder dat je browser deze gaat lezen als JavaScript (dit veroorzaakt dus een syntax-error). Daarom is er in JavaScript net als in HTML de mogelijkheid om commentaar te gebruiken. Dit is echter niet het HTML-commentaar (<!-- en -->). HTML-commentaar kan geen tekst verbergen voor JavaScript, maar alleen voor HTML. Er zijn twee soorten commentaar in JavaScript: // en /* ... */. Voor één regel commentaar kunnen we vaak volstaan met //, voor meerdere regels moeten /* en */ gebruikt worden. Een voorbeeld:
Nu ga ik het hebben over belangrijke opdrachten in JavaScript die veel gebruikt worden. Om deze tutorial vanaf het begin goed te kunnen doen in het noodzakelijk om ze voor een groot deel nu te leren te kennen.

document.write() zet tekst in het scherm. Wanneer dit tijdens het laden van je pagina is, wordt de tekst gewoon op de juiste plek in de pagina gezet (in de volgorde van de broncode. Maar wanneer de pagina wel al geladen is wordt de tekst door deze opdracht in een nieuwe pagina gezet. (Met het gebruik van een event-handler (bijv. onload) wordt de tekst in een nieuwe pagina gezet, zonder event-handler niet.
document.write() tijdens het laden van de pagina:
document.write() na het laden van de pagina:
document.writeln() doet hetzelfde als document.write(), maar dan met een regeleinde achter de tekst. Dit is geen <br>-tag en wordt dus in een browservenster weergeven als een spatie, wanneer je geen <pre>-tags gebruikt.

document.open() kun je na het laden van je pagina gebruiken als je alvast een nieuwe pagina wilt openen voordat je document.write() gaat gebruiken.
Het nut van deze opdracht is mij eerlijk gezegd niet helemaal duidelijk. Misschien is het nodig bij oude browsers.

document.close() sluit het schijven van tekst in een nieuwe pagina af. Dit is nodig om het laden van deze nieuwe pagina te voltooien. (Pas bij document.close() vindt het onload-event plaats in de nieuwe pagina!) Wanneer je na het gebruik van document.close() in de nieuwe pagina weer document.open() en/of document.write() gebruikt wordt er wéér een nieuwe pagina geopend. Maar als je document.close() niet gebruikt hebt wordt de tekst gewoon in de eerste nieuwe pagina gezet bij de eerder geplaatste tekst.

window.alert() geeft een normaal dialoogvenster met tekst en een OK-knop.

window.confirm() geeft een dialoogvenster met tekst, een OK-knop en een Annuleren-knop.
Klikken op OK geeft true als waarde terug. Annuleren geeft false terug. Dit zijn twee boolean-waarden. De betekenis van boolean-waarden zal later in deze tutorial duidelijk worden.

window.promt() geeft een dialoogvenster met tekst, een invulvak, een OK-knop en een Annuleren-knop. Als je op OK drukt is de tekst die je ingevuld hebt de waarde die teruggegeven wordt. Druk je op Annuleren, dan wordt de waarde null teruggegeven.

window.open() opent een nieuw venster. Dit kan onder andere een venster zonder toolbalk, statusbalk en scrollbalk zijn dat niet van grote te veranderen is (popupvenster). Hierover heb ik het later in deze tutorial nog.

window.close() sluit het venster. Als dit geen nieuw geopend venster is, maar het hoofdvenster van de browser, zal de browser eerst om bevestiging vragen of je het venster wel echt wilt sluiten.

Combinaties van deze opdrachten zijn ook mogelijk. Bijvoorbeeld het eerder in deze tutorial genoemde window.open().document.write(). Maar ook window.open().alert() kan. Enzovoorts.

De bovenstaande opdrachten, waarbij je steeds haakjes moet gebruiken, zijn voorbeelden van methoden. Methoden zijn functies. Er zijn echter ook belangrijke eigenschappen (properties) die zeker genoemd moeten worden. Eigenschappen zijn variabelen. Deze moeten gedefinieerd worden met een is-teken =. In de hoofdstukken Variabelen, Functies en Objecten in deze tutorial vertel ik wat de begrippen variabelen en functies precies betekenen.
Hier volgen belangrijke eigenschappen:

window.status bepaald wat voor tekst er in de statusbalk staat.
location.href brengt je naar een andere pagina. Je mag ook window.location.href, window.location of location gebruiken.

Voorbeeld:
Het vermelden van het window-object is trouwens bijna nooit verplicht. Je mag ook gewoon alert(), confirm(), open(), close(), etc. schrijven. Ikzelf heb de voorkeur om het wel te doen, om het bijvoorbeeld makkelijker te scheiden van het document-object, aangezien de methode document.alert() niet bestaat en de methoden document.open() en document.close() heel andere methoden zijn dan window.open() en window.close(). De vermelding van het document-object moet echter wel altijd. Meer over window en document vertel ik in het hoofdstuk Browserobjecten.

Ten slotte moet ik nog even opmerken dat JavaScript een hoofdletter- en leestekengevoelige taal is.
Doordat JavaScript hoofdlettergevoelig is zijn bijvoorbeeld Document.write(), Window.open() en WINDOW.ALERT() geen bestaande methoden. In VBScript is het uitvoeren van deze methoden geen probleem, maar in JavaScript geeft het een fout. In VBScript heet een functie die a() heet ook A(), maar in JavaScript is a() een andere functie dan A(). Hetzelfde geldt ook voor variabelen.
En bij de gevoeligheid wat betreft het gebruik van leestekens moet je denken aan fouten die kunnen optreden wanneer je puntkomma's en aanhalingstekens gebruikt. In principe moet je in JavaScript alle opdrachten van elkaar scheiden met puntkomma's, behalve als je regeleindes
gebruikt, want dan zijn ze niet verplicht. Voorbeeld:
Dit script geeft een fout. Maar het volgende script niet:
En dit mag ook:
Het is echter goed om het aan te wennen altijd puntkomma's te gebruiken en veel regeleinden toe te passen, om het simpel en overzichtelijk te houden:
In JavaScript hebben aanhalingstekens (" en ') een andere en striktere betekenis dan in HTML. Er is een groot verschil tussen wel en geen aanhalingstekens. Ook is het vaak belangrijk om er op te letten of je enkele aanhalingstekens (') of dubbele aanhalingstekens (") gebruikt. Aanhalingstekens geven aan dat iets een string is. Meer over aanhalingstekens en over wat strings zijn vertel ik later in deze tutorial.
En ten slotte is het nog belangrijk iets om te weten over de namen van variabelen en functies, waarvan ik ook in de komende hoofdstukken zal vertellen wat dit precies zijn. Namelijk dat de namen nooit mogen beginnen met een cijfer, maar alleen met een letter. De tekens na het eerste teken van een naam mogen wel gewoon zowel letters als cijfers zijn. Andere tekens dan letters en cijfers mogen echter helemaal niet in de namen van variabelen en functies voorkomen. Dus geen komma's, aanhalingstekens, vraagtekens, uitroeptekens, enzovoorts.

Terug naar Inhoudsopgave


Events

In dit hoofdstuk heb ik het over events. Onder events worden gebeurtenissen verstaan zoals klikken op de muis, bewegen met de muis, drukken op een toets, het openen (laden) van een pagina, het sluiten van een pagina, enzovoorts. Kortom, dingen die de bezoeker van een pagina doet op de pagina. Met JavaScript is het mogelijk om op allerlei manieren op allerlei gebeurtenissen te reageren. Met alleen HTML is dit maar zeer beperkt mogelijk. Het is met HTML namelijk slechts mogelijk om te reageren op het klikken op een link. En ook de reactie op het klikken stelt niet zo veel voor. We kunnen met HTML slechts nieuwe locaties opgeven en bepaalde plekken binnen een document opzoeken (met anchors), door het gebruik van het href-attribuut in een a-tag. JavaScript kunnen we echter gebruiken bij allerlei events, in allerlei HTML-elementen.

Het reageren op events in JavaScript gebeurt, zoals ik al eerder uitgelegd heb in deze tutorial, met event-handlers. Hieronder heb ik een de meest belangrijke event-handlers genoemd en de betekenis ervan uitgelegd:

onclick - klikken met de linkermuisknop.

ondblclick - dubbelklikken met de linkermuisknop.

onmousedown - een muisknop indrukken.

onmouseup - een ingedrukte muisknop loslaten.

onmouseover - de muis ergens op plaatsen.

onmouseout - de muis ergens van afhalen.

onmousemove - met de muis bewegen.

onkeypress - drukken op een toets.

onkeydown - een toets indrukken.

onkeyup - een ingedrukte toets loslaten.

onmousewheel - draaien aan het wieltje op je muis.

onscroll - scrollen met de scrollbalk.

onresize - het browservenster van grootte veranderen.

onload - pagina geladen.

onunload - pagina sluiten.

onfocus - de cursor/focus ergens op zetten.

onblur - de cursor/focus ergens van weghalen.

onhelp - de Windows help opvragen.

oncut - knippen.

oncopy - kopiëren.

onpaste - plakken.

onselectstart - selecteren.

oncontextmenu - het snelmenu openen (met rechtermuisknop).

onsubmit - een formulier verzenden.

onreset - een formulier wissen

Er zijn twee manieren om event-handlers te gebruiken. Je kunt een event-handler als attribuut in een HTML-tag plaatsen en je kunt ze gebruiken in JavaScript zelf. Bij het gebruik van event-handlers in HTML is het verschil tussen hoofletters en kleine letters niet belangrijk: je mag bijvoorbeeld onclick gebruiken, onClick, OnClick, ONCLICK, oNcLiCk, of hoe je het ook maar wilt. Het werkt allemaal.
Het is echter zo dat niet alle event-handlers in elke tag gebruikt kunnen worden. Voor event-hanlers in HTML geld het volgende:

onclick - werkt in vrijwel elk HTML-element.

ondblclick - werkt in vrijwel elk HTML-element.

onmousedown - werkt in vrijwel elk HTML-element.

onmouseup - werkt in vrijwel elk HTML-element.

onmouseover - werkt in vrijwel elk HTML-element.

onmouseout - werkt in vrijwel elk HTML-element.

onmousemove - werkt in vrijwel elk HTML-element.

onkeypress - werkt in vrijwel elk HTML-element.

onkeydown - werkt in vrijwel elk HTML-element.

onkeyup - werkt in vrijwel elk HTML-element.

onmousewheel - werkt in vrijwel elk HTML-element.

onscroll - werkt alleen in de <body>-tag.

onresize - werkt alleen in de <body>-tag.

onload - werkt alleen in de <body>-tag.

onunload - werkt alleen in de <body>-tag.

onfocus - werkt in vrijwel elk HTML-element.

onblur - werkt in vrijwel elk HTML-element.

onhelp - werkt in vrijwel elk HTML-element.

oncut - werkt in vrijwel elk HTML-element.

oncopy - werkt in vrijwel elk HTML-element.

onpaste - werkt in vrijwel elk HTML-element.

onselectstart - werkt in vrijwel elk HTML-element.

oncontextmenu - werkt in vrijwel elk HTML-element.

onsubmit - werkt alleen in een <form>-tag.

onreset - werkt alleen in een <form>-tag.

Bij het gebruik van event-handlers in JavaScript is het verschil tussen hoofdletters en kleine letters wel belangrijk: alleen onclick werkt. onClick, OnClick, ONCLICK, oNcLiCk werken niet. Event-handlers moeten met kleine letters getypt worden in JavaScript.
In JavaScript gaat het definiëren van een event-handler heel anders dan in HTML. Het gaat namelijk bijvoorbeeld zo:

document.onclick = function()
{
    window.alert("Hallo!");
};

Of zo:

document.onclick =
new Function("window.alert('Hallo!')");

Wat je op beide manier doet is een functie toekennen aan de event-handler onload van het object document. Een event-handler definiëren als functie is noodzakelijk om er een opdracht aan te koppelen. Dit is dus fout:

document.onclick = window.alert("Hallo!");

Als je een event-hanler in HTML gebruikt wordt er in feite al automatisch een functie van de event-handler gemaakt. Dit doet hetzelfde als de boven genoemde opdrachten:

<body onclick="window.alert('Hallo!')">

Hoe het allemaal precies werkt met functies leg ik nog uit in de hoofdstukken Functies en Objecten.
De regels wat betreft welke event-handler voor welk HTML-element kan worden gebruikt komen in JavaScript op zich overeen met die in voor event-handlers in HTML, maar toch is er een verschil: de event-handlers van de body zijn namelijk vaak ook als eigenschap van het window-object en/of van het document-object te gebruiken. Hier volgt een schema:

onclick - eigenschap van vrijwel elk HTML-element en van window.

ondblclick - eigenschap van vrijwel elk HTML-element en van window.

onmousedown - eigenschap van vrijwel elk HTML-element en van window.

onmouseup - eigenschap van vrijwel elk HTML-element en van window.

onmouseover - eigenschap van vrijwel elk HTML-element en van window.

onmouseout - eigenschap van vrijwel elk HTML-element en van window.

onmousemove - eigenschap van vrijwel elk HTML-element en van window.

onkeypress - eigenschap van vrijwel elk HTML-element en van window.

onkeydown - eigenschap van vrijwel elk HTML-element en van window.

onkeyup - eigenschap van vrijwel elk HTML-element en van window.

onmousewheel - eigenschap van vrijwel elk HTML-element en van window.

onscroll - eigenschap van de body (document.body) en van window.

onresize - eigenschap van de body (document.body) en van window.

onload - eigenschap van de body (document.body) en van window.

onunload - eigenschap van de body (document.body) en van window.

onfocus - eigenschap van vrijwel elk HTML-element en van window.

onblur - eigenschap van vrijwel elk HTML-element en van window.

onhelp - eigenschap van vrijwel elk HTML-element en van window en document.

oncut - eigenschap van vrijwel elk HTML-element.

oncopy - eigenschap van vrijwel elk HTML-element.

onpaste - eigenschap van vrijwel elk HTML-element.

onselectstart - eigenschap van vrijwel elk HTML-element en van document.

oncontextmenu - eigenschap van vrijwel elk HTML-element en van document.

onsubmit - eigenschap van formulier-elementen.

onreset - eigenschap van formulier-elementen.

Twee dingen die hetzelfde doen:

In JavaScript is er naast alle event-handlers ook nog een event-object, met een aantal nog geavanceerdere dingen dan alleen met event-handlers beschikbaar zijn. Ik moet er nu op wijzen dat er wel verschillen zijn tussen browsers, wat betreft het event-object. Vooral in Netscape en Firefox werkt het anders dan in Internet Explorer. Ik begin met een uitleg over hoe het werkt in Internet Explorer.
In Internet Explorer is er een object genaamd event. De eigenschappen die dit object bevat en zelfs ook het bestaan van dit object hangen af van het event dat op dat moment plaatsvindt en daarom ook van waar je script staat, in een event handler of daar buiten. Het event-object in document.onmousemove is bijvoorbeeld anders dan het event-object dat zich bevind in document.onkeydown. En als je buiten een event handler werkt, is er ook geen event-object (dan heeft het de waarde null) beschikbaar. Hier volgen de belangrijkste eigenschappen ervan:

button - Muisknopnummer.

keyCode - Toetsnummer. Bevat bij onkeypress andere waarden dan bij onkeydown en onkeyup. Bevat bij onkeydown dezelfde waarden als bij onkeyup.

ctrlKey - Ctrl-toets. Ingedrukt geeft true. Niet ingedrukt geeft false.

altKey - Alt-toets. Ingedrukt geeft true. Niet ingedrukt geeft false.

shiftKey - Shift-toets. Ingedrukt geeft true. Niet ingedrukt geeft false.

clientX - Muispositie in horizontale richting in pixels.

clientY - Muispositie in verticale richting in pixels.

Nu drie voorbeelden voor Internet Explorer(in de statusbalk):
In Netscape/Firefox bestaat er in tegenstelling tot in Internet Explorer niet een algemeen event object, maar we moeten er een uit de functie halen. Dit doen we door een variabele te zetten tussen de ronde haakjes ( ) van de functie die we toekennen aan een event-handler. Zo'n variabele wordt een parameter genoemd. Wat parameters precies zijn leg ik nog uit in het hoofdstuk Functies. Het speciale aan deze event parameter is dat deze automatisch zijn waarde toegekend krijgt bij het plaatsvinden van het event. De parameter is automatisch gedefinieerd als een event-object.
Tegenwoordig hebben Netscape en Internet Explorer ondanks hun verschillende aanroepmanier wel overeenkomst in eigenschappen van het event-object. In deze tutorial wil ik vooral uitgaan van moderne browsers en daarom zal ik het nu niet hebben over hoe het in oude Netscape-versies werkte met events. Wel wil ik opmerken dat je in Netscape/Firefox ook which kunt gebruiken in plaats van button. Hier heb drie voorbeelden voor Netscape/Firefox met de letter e als event-object (in de statusbalk):
Er is een hele goede oplossing voor het probleem van het verschil tussen de browsers. Zoiets is namelijk mogelijk door met een beetje handigheid het script zodanig in elkaar te zetten dat het controleert op de mogelijkheden van de browser die wel of niet geboden worden en dat het de geboden mogelijkheden dan gebruikt. We kijken simpelweg of de paramater e geen waarde heeft en kennen wanneer dat zo is het algemene event-object toe aan de parameter e. Voorbeeld (in de statusbalk):
De werking van dit script is op een nog niet eerder in deze tutorial besproken manier, maar in het hoofdstuk Statements zal ik uitgebreid uitleggen hoe if-opdrachten zoals hierboven werken.

Terug naar Inhoudsopgave


Variabelen

Variabelen zijn (ingebouwde of zelfgedefinieerde) woorden of letters waaraan een waarde kan worden toegekend. Dit kunnen verschillende typen waarden zijn:
 - object (o.a. array).
 - string.
 - number.
 - boolean.
 - function.
 - undefined.

Wat deze datatypen precies zijn zal vooral later in deze tutorial duidelijk worden, maar ik zal er wel een korte uitleg bij geven:

Object: betekend dat de variabele een object is, oftewel dat het meerdere waarden bevat, opgeslagen in eigenschappen en methoden en/of in een numerieke index (array).
String: een tekenreeks, tekst, die zowel uit letters als cijfers kan bestaan. String-waarden staan tussen aanhalingstekens (" of ').
Number: een getal, decimaal of heel, dat niet tussen aanhalingstekens staat.
Boolean: twee waarden, true of false.
Function: een functie. Dit is dus geen variabele meer.
Undefined: ongedefinieerd. De variabele bevat geen waarde.

De aanroep van een van een variabele is eenvoudig: geen haakjes gebruiken zoals bij een functie en geen aanhalingsteken gebruiken (niet verwarren met een string dus).
Om het datatype van een variabele te zien kun je het statement typeof gebruiken.

Iets toekennen aan een variabele doe je met een is-teken =. Als je een variabele toekent aan een variabele in plaats van een waarde, wordt automatisch de waarde ervan doorgegeven. Als je functie aan een variabele toekent, wordt die variabele een functie.
Hier volgt een voorbeeld van een script met variabelen:
Vóór of bij het definiëren van de waarde van een variabele kunnen we een variabele ook nog declareren, namelijk met var. In de taal JavaScript is dit echter vaak niet nodig, we kunnen ook een niet van gedeclareerde variabele een waarde geven. Dit geeft geen fout.
In veel andere talen, bijvoorbeeld Java, is het wel altijd nodig een variabele te declareren voor we er een waarde aan kunnen geven. Een voorbeeld van een situatie waarin een declaratie wel handig kan zijn is er als we van een nog niet gedefinieerde variabele foutloos een waarde willen kunne controleren. Dat kun je in plaats van te declaren overigens ook oplossen door window. plus die varabelenaam te schrijven (door de variabele dus als eigenschap van het window-object aan te roepen, aangezien een een variabele hier automatisch eigenschap van wordt als deze gedefinieerd is).
Voorbeeld van declaraties:
Een situatie waarin we declaraties echt nodig hebben krijgen we wanneer we op verschillende plaatsen in een HTML-document dezelfde variabelenaam dubbel willen kunnen gebruiken. We moeten een variabele dan dus voor bepaalde plaatsen onbeschikbaar kunnen maken in het document. Declareren heeft namelijk een belangrijke werking: als een variabele gedeclareerd is binnen een functie is deze alleen daarin beschikbaar, en niet erbuiten.
Zo'n beperkt beschikbare variabele wordt een locale variabele genoemd. Alle normale variabelen, die overal beschikbaar zijn, worden globale variabelen genoemd. Lokale variabele zijn geen onderdeel van het window-object.

Terug naar Inhoudsopgave


Functies

Functies zijn aanroepbare codes die opdrachten kunnen uitvoeren. Ze kunnen even als variabelen ingebouwd zijn in JavaScript of zelf worden gemaakt.
Het handige van functies die je zelf maakt is dat je een script beter kunt indelen in een HTML-document en dat je één functie meerdere keren kunt gebruiken. Je kunt bijvoorbeeld een groot script in een functie plaatsen tussen script-tags en dan slechts de aanroep van deze functie in meerdere event-handlers zetten die in je document staan.

In JavaScript moet een functie altijd met haakjes worden aangeroepen, dit is in tegenstelling tot bijvoorbeeld VBScript. Je kunt wel foutloos window.alert in je document zetten in plaats van window.alert(), maar er zal gewoon niks gebeuren, omdat dit slechts geldt als het noemen van de functie en niet als een aanroep.

Een functie moet gedeclareerd worden met het statement function, om aan te geven dat het gaat om een functie. Ook moeten er haakjes ( ) gebruikt worden achter de naam van de functie.

De inhoud van een functie definiëren we tussen accolades { }, achter de haakjes. Hier een voorbeeld van een functie die uitgevoerd wordt als je op links klikt:
Het goede functies is ook de mogelijkheid om parameters te gebruiken. Parameters worden ook wel argumenten genoemd. Het zijn variabelen en hun waarden die je meegeeft aan een functie, tussen de haakjes ( ). De naam van de parameter zet je tussen de haakjes van de functiedefinitie, de waarde van de parameter geef je door bij de functieaanroep. Als je meerdere parameters gebruikt scheid je deze van elkaar door komma's. De volgorde van de parameterwaarden bij de aanroep is hetzelfde als de volgorde van de parameternamen bij de functiedefinitie. Een voorbeeld van een functie met een parameter param die de tekst bepaalt in een dialoogvenster:
En hier volgt een voorbeeld van een functie met meerdere parameters:
Een belangrijk kenmerk van parameters waar je op moet letten is dat het lokale variabelen zijn. Ze zijn alleen beschikbaar in de functie, niet er buiten.
De meeste ingebouwde functies in JavaScript hebben trouwens ook parameters. Denk maar bijvoorbeeld aan document.write() window.alert(), die parameters gebruiken voor de tekst die je wilt tonen.

Misschien is het je al opgevallen dat ik af en toe in deze tutorial het statement return heb gebruikt. Met return kun je een functie een waarde geven. Zo kun je een functie in feite dus als een soort variabele gebruiken. Voorbeeld (in de statusbalk en in dialoogvenster):
Tegelijkertijd is het trouwens ook zo dat een functie stopt bij het tegenkomen van return. Dit is handig als je bijvoorbeeld controles wilt uitvoeren waarbij je dan voorwaardelijk de functie afbreekt met return of juist verdergaat met de functie. Hier een voorbeeld waarbij de tweede window.alert()-opdracht die er staat niet uitgevoerd wordt:
De werking van events is afhankelijk van terug gegeven waarden. Daarom kun je met return de werking van events in- en uitschakelen. Dit kan door de waarden true en false te gebruiken als je een event-handler herdefinieert. En dit is wat ik al eerder in deze tutorial in scripts heb gezet. Alles wat na return false bij een event zou moeten plaatsvinden vindt niet plaats door deze opdracht. Op deze manier kun je bijvoorbeeld een onclick-opdracht uitvoeren in een link zonder de href-opdracht ook uit te voeren. En je kunt zo ook een onsubmit-opdracht uit voeren zonder een formulier te verzenden (action-opdracht). De event-handlers in een HTML-element worden namelijk eerder uitgevoerd dan de andere attributen er in. Hier drie voorbeelden. Bij de eerste voorbeelden wordt de href-opdracht gewoon uitgevoerd, maar bij de derde niet:
Klik

Klik

Klik

Nu zul je waarschijnlijk denken: "maar dit zijn toch helemaal geen functies!". Maar dit zijn het wel. In een event-handler zit in feite een automatische functie ingebouwd. Dit blijkt namelijk wanneer we vanuit een JavaScript event-handlers gaan gebruiken. Dan moeten we gewoon een functie gebruiken om iets aan de event-handlers toe te kennen. Dit heb ik ook in het hoofdstuk Events verteld.

Er is, zoals al in het hoofdstuk Events min of meer duidelijk werd, naast de normale manier om een functie te definiëren ook variabele-definieer-manier om een functie te maken, of beter: er zijn een ook een aantal variabele-definieer-manieren om een functie te maken.
Je kunt eerst een functie maken en de naam er van zonder haakjes (je wilt alleen de naam noemen van de functie, je wilt de functie niet direct uitvoeren) toekennen aan een variabele:

function functie1()
{
    window.alert("Functies zijn handig.");
}
functie2 = functie1;

Op de bovenstaande manier is functie2 een soort "kopie" van functie1. Precies hetzelfde geldt voor de hier onderstaande manier, waarin de we functiedefinitie direct aan de variabele functie2 plakken:

functie2 = function functie1()
{
    window.alert("Functies zijn handig.");
};

Zo hebben we ook twee dezelfde functies, functie1 en functie2. Als we alleen een functie2 willen, kunnen we nu ook de naam van functie1 weglaten:

functie2 = function()
{
    window.alert("Functies zijn handig.");
};

Een functie kan ook in één keer aan meerdere variabelen worden toegekend:

functie4 = functie3 = functie2 = function()
{
    window.alert("Functies zijn handig.");
};

En dan een totaal andere manier, waarin we een functie aanmaken zoals we een object definiëren:

functie1 =
new Function("window.alert('Functies zijn handig.')");

Bij deze manier moeten we er aan denken dat we het statement new niet vergeten, dat Function met een hoofdletter is en dat we de opdracht in de functie als een parameter tussen aanhalingstekens tussen ronde haakjes plaatsen. Om een functie te maken kunnen we dus een functie gebruiken die Function heet.
Verdere uitleg over het definiëren objecten geef ik in het hoofdstuk Objecten.

Terug naar Inhoudsopgave


Statements

In JavaScript (en ook in andere talen) zijn er termen, codes, om o.a. aan te geven hoe dingen moeten worden gedefinieerd, welke opdrachten wel en niet moeten worden uitgevoerd, hoe vaak opdrachten moeten worden uitgevoerd en wanneer ze moeten worden uitgevoerd.
Het gaat hier om zogenaamde statements. In dit hoofdstuk vertel ik over belangrijke statements, die met controleopdrachten te maken hebben.

Heel vaak worden if en else gebruikt. Met deze statements kun je logische bewerkingen uitvoeren. Je voert op basis van voorwaarden, die true of false kunnen zijn, opdrachten uit. De syntaxis van alleen een if-opdracht is als volgt:

if (voorwaarde) opdracht

Als de voorwaarde true is wordt de opdracht uitgevoerd. Voorbeeld:
Met dit if-statement wordt gecontroleerd of de variabele x de waarde 8 bevat. Dit is niet zo, het is false. De window.alert(x)-opdracht wordt daarom niet uitgevoerd. Maar als we x wel de waarde acht geven, wordt de opdracht wel uit gevoerd. We krijgen in een dialoogvenster de waarde van x te zien (8 dus). Probeer het maar.
Als we meerdere opdrachten willen uitvoeren op basis van één voorwaarde, kunnen we ook met één if-opdracht volstaan, maar we moeten dan wel aangeven met accolades { } dat de opdrachten allemaal bij het if-statement horen (anders worden alle opdrachten na de eerste opdracht onafhankelijk van het if-statement uitgevoerd):
Door het bovenstaande script wordt de waarde van x zowel in een dialoogvenster getoond als in de statusbalk, als deze acht is. Maar omdat x nu geen acht is gebeurt er niets.
Met het statement else is het mogelijk om een alternatieve opdracht uit te voeren als de if-voorwaarde false is:
Ook voor else geldt dat je bij meerdere opdrachten accolades moet gebruiken.
Als je nog meer voorwaarden en daarbij horende opdrachten op wilt, kun je ook nog de combinatie else if gebruiken:
In plaats van else if kun je vaak ook gewoon een paar keer if gebruiken. Maar bedenk daarbij wel dat je dan aparte statements hebt die niet meer met elkaar samenhangen. Hierdoor kan een bepaalde if-opdracht de werking van een andere if-opdracht verhinderen. In het volgende voorbeeld is daar duidelijk sprake van:
Door te klikken met de muis op de pagina verandert de eerste if-opdracht, die controleert of de achtergrond wit is, de achtergrondkleur van wit naar zwart. Maar vervolgens verandert een de tweede if-opdracht, die controleert of de achtergrondkleur zwart is, de achtergrondkleur direct weer naar wit.
Als we echter willen dat de achtergrondkleur door de ene keer te klikken zwart wordt en dat de achtergrondkleur na nog een keer te klikken weer wit wordt, dan moeten we else if gebruiken:
Nu kan er altijd maar één van beide opdrachten worden uitgevoerd, omdat ze bij elkaar horen.
(Let er trouwens op dat je de achtergrondkleur altijd controleert in kleine letters. Bij het gebruik van hoofdletters in de voorwaarde is het resultaat false. In JavaScript wordt namelijk altijd een kleurwaarde in kleine letters teruggegeven.)
Het is belangrijk om even op te merken dat je altijd een dubbel is-teken moet gebruiken om een waarde van een variabele te controleren, aangezien je met een enkel is-teken een waarde toekent aan een variabele. Als je een enkel is-teken gebruikt in een if-voorwaarde ben je niet alleen aan het controleren maar ook aan het toekennen, waardoor dus de fout optreedt dat de if-voorwaarde automatisch true wordt.

Naast de if-else-statements is nog een soort logica-statements, namelijk switch, case en default. Een switch-case-default-opdrachten-blok zit als volgt in elkaar (het gebruik van accolades { } is altijd vereist):

switch (variabele / waarde teruggevende functie)
{
    case "waarde1" :
        opdracht1;
    case "waarde2" :
        opdracht2;
    case "waarde3" :
        opdracht3;
    case "waarde4" :
        opdracht4;
    case "waarde5" :
        opdracht5;
    default :
        opdracht bij andere waarde;
}

Tussen de haakjes van het switch-statement zet je dus een variabele of een waarde returnende functie. Achter elk case-statement zet je een waarde. Achter een dubbele punt die je achter de waarde zet, zet je een opdracht. Deze opdracht wordt uitgevoerd als de waarde die er voor staat, voor de dubbele punt, de waarde van de variabele/functie bij het switch statement is. Ook als een waarde van een eerder case-statement de waarde van de variabele/functie is wordt de opdracht uitgevoerd. Dat betekend dus dat vanaf het case-statement met de waarde die bij de variabele hoort alle er opvolgende opdrachten van alle case-statements worden uitgevoerd.
Het default-statement ten slotte bevat een opdracht die uitgevoerd wordt als er geen enkele waarde van de genoemde waarden bij de variabele hoort.
Om tegen te houden dat er meerdere opdrachten worden uitgevoerd bij een waarde, kun je het statement break gebruiken:

switch (variabele / waarde teruggevende functie)
{
    case "waarde1" :
        opdracht1;
        break;
    case "waarde2" :
        opdracht2;
        break;
    case "waarde3" :
        opdracht3;
        break;
    case "waarde4" :
        opdracht4;
        break;
    case "waarde5" :
        opdracht5;
        break;
    default :
        opdracht bij andere waarde;
}

Er hoort nu bij elk case-statement maar één opdracht.
Hier een voorbeeld van het gebruik van switch-, case-, default- en break-statements:
In dit script wordt er eerst een prompt-venster geopend, waarin je een letter kunt in vullen en dan op OK of Annuleren kunt klikken. De ingevulde waarde in het venster wordt toegekend aan de variabele letter, als je OK gekozen hebt. Vervolgens controleert een if-statment of letter een waarde heeft en of die waarde een lengte heeft van maar een teken. Zo ja dan gaat het script verder. Een switch-case-default-blok kiest dan een opdracht er bij die aan een variabele nr een string-waarde doorgeeft die aangeeft om de hoeveelste letter van het alfabet het gaat. Deze waarde wordt getoond tussen de tekst in een dialoogvenster. Maar als het geen letter van het alfabet is wordt door een default-opdracht de waarde "geen" doorgegeven aan nr. En dan wordt dit dus tussen de tekst in het dialoogvenster gezet.

Een handig statement is het with statement. Met dit statement kun je eerst de naam van een object noemen tussen ronde haakjes en vervolgens kun je bij de aanroep van onderdelen die binnen dat object horen de naam van het object weglaten. Met accolades { } geef je aan wat er bij het with-statement hoort. Zo zit een with-blok in elkaar:

width (object)
{
    opdracten
}

Voorbeeld:
Dit is dus in plaats van document.write().

Het is in JavaScript (en ook in de meeste andere talen) mogelijk om iets herhaald uit te voeren, net zo lang tot er niet meer aan een bepaalde voorwaarde wordt voldaan. Men noemt zulke opdrachten lussen. Er zijn drie soorten lussen: for-lussen, (do-)while-lussen en functies die zichzelf aanroepen.
Een for-lus is als volgt opgebouwd:

for (definiëring; voorwaarde; stap)
{
    opdrachten
}

De woorden definiëring, voorwaarde en stap slaan op een variabele met een nummer als waarde, die je gebruikt om het begin van de lus, het einde van de lus en elke stap van de lus te bepalen. Een voorbeeld zal dit misschien verduidelijken. We definiëren een variabele i, met de waarde 1 (i = 1). Als voorwaarde voor de uitvoering van de lus geven we aan dat de variabele maximaal de waarde tien mag bevatten op de lus uit te voeren (i <= 10). We verhogen de variabele, tijden elke stap dat de lus uit gevoerd wordt, met de waarde 1 (i = i + 1). De opdracht die uit gevoerd wordt door de lus zet steeds tekst in venster met de waarde van de variabele. De lus waar ik het nu over heb ziet er zo uit:
Het resultaat van de lus ziet er zo uit:


De lus wordt dus tien keer herhaald omdat na tien keer i de waarde 10 heeft gekregen.
Als we niet aangeven in de lus dat i met verhoogd wordt bij elke stap maar dat deze bijvoorbeeld verlaagd wordt, terwijl we de voorwaarde i <= 10 aanhouden, dan krijgen hebben we een oneindige lus. Doordat zo'n lus niet stopt met herhalen kan je browser traag gaan reageren en op een gegeven moment zelfs vastlopen. Het is met het maken van lussen dus goed oppassen dat je geen foutjes maakt ...

Eenvoudiger dan for-lussen zijn while-lussen. Bij deze lussen moet je op een andere plaats dan in de ronde haakjes de beginwaarde van je variabele en de stapgrote bepalen. Een while-lus zit zo in elkaar:

while (voorwaarde)
{
    opdrachten
}

Als je het zelfde wilt doen met deze lus als met een for-lus dan kan dat zo:
De beginwaarde van je variabele stel je dus voor je lus vast en de verandering van de waarde van je variabele zet je dus gewoon tussen de accolades.
Je kunt bij een while lus ook eerst de opdracht(en) noemen en daarna de voorwaarde, als je het statement do gebruikt. Dit gaat zo:

do
{
    opdrachten
}
while (voorwaarde)

Voorbeeld:
De precieze betekenis van o.a. <= en + leg ik trouwens in het volgende hoofstuk Operators uit.

Als je de werking van een lus heel geavanceerd wilt bepalen kun je vaak het beste gewoon een functie maken die zichzelf aanroept. Het ontstaan van een lus door een functie die zichzelf aanroept wordt recursie genoemd. Als voorbeeld zullen we nu een functie maken die we myloop() noemen. In de functie zetten we dezelfde document.write()-opdracht als in de eerder genoemde voorbeeldlussen en we gebruiken een if-statement om het einde van de lus te bepalen. Op twee plaatsen roepen we de functie aan: buiten de functie om deze te starten en in de functiedefinitie om de functie steeds zichzelf aan te laten roepen. Dit is de functie:

Terug naar Inhoudsopgave


Operators

In deze tutorial zijn al een aantal wiskundige tekens aan bod gekomen. Omdat de betekenis van deze tekens misschien lang niet altijd duidelijk is, is het goed hier een hoofdstuk over te hebben. In dit hoofdstuk heb ik het over de rekentekens van JavaScript. Ze worden operators genoemd.

De operator die het meest gebruikt wordt in JavaScript is het is-teken =. Over deze operator valt maar weinig te vertellen: je kent er een waarde mee toe aan een variabele. Links van het teken schrijf je de naam van de variabele en rechts wat je er aan toe kent.

De operators +, -, *, / zijn operators voor het maken van normale berekeningen:
+ telt op.
- trekt af.
* vermenigvuldigt.
/ deelt.
% deelt geeft een restwaarde terug (modulus).

Maar een plusteken + heeft ook nog een tweede betekenis. Je kunt er namelijk, zoals je al vele malen eerder in deze tutorial hebt gezien, ook dingen mee aan elkaar vastplakken tot een string, in plaats van bij elkaar optellen. Als een van de dingen die je koppelt met het plusteken namelijk een string is worden de waarden aan elkaar vastgeplakt. Is er geen string, alleen dan wordt er opgeteld. Voorbeeld:
Dit script toont number-waarde 2. Maar het volgende script geeft een string-waarde "11":
Doordat er hier aanhalingstekens om de 1 van b staan, is het string. Het is echter mogelijk om van een string weer een number te maken. Dit gebeurt automatisch als we ook een andere berekening dan optellen uitvoeren, bijvoorbeeld een vermenigvuldiging:
De uitkomst van 1 * b is een number-waarde 1. Deze wordt opgeteld bij a. In dit script bevat c dus weer wel de number-waarde 2.

De operator - heeft óók een tweede betekenis: van een positief getal een negatief getal maken. Dit kan bijvoorbeeld zo:

De operators ++ en -- hebben een wat uitgebreidere betekenis:
++ verhoogt de waarde van een variabele met 1 en kent deze verhoogde waarde toe aan die variabele.
-- verlaagt de waarde van een variabele met 1 en kent deze verlaagde waarde toe aan die variabele.

++ en -- zijn in feite afgekorte sommen:
x ++ betekent het zelfde als x = x + 1.
x -- betekent het zelfde als x = x - 1.
Daarom zijn deze handig in bijvoorbeeld het stapgedeelte van lussen:
Resultaat van deze lus:

Resultaat van deze lus:

Operators die ook afgekorte sommen vormen, dat zijn +=, -=, *=, /=:
+= telt op en kent toe (of plakt vast, bij strings).
-= trekt af en kent toe.
*= vermenigvuldigt en kent toe.
/= deelt en kent toe.
%= geeft delingsrest en kent toe.

x += 1 betekent hetzelfde als x = x + 1.
x -= 1 betekent hetzelfde als x = x - 1.
x *= 1 betekent hetzelfde als x = x * 1.
x /= 1 betekent hetzelfde als x = x / 1.
x %= 1 betekent hetzelfde als x = x % 1.

Ook deze operators kunnen handig zijn bij het maken van lussen:
Resultaat van deze lus:

Resultaat van deze lus:

Resultaat van deze lus:

Resultaat van deze lus:

Om te controleren of vergelijkingen kloppen of niet, en of dingen bestaan of niet, (of iets true of false is dus) zijn er logische, controlerende operators, ==, !=, !, <, >, <=, >=, &&, ||:
== controleert of twee waarden gelijk aan elkaar zijn.
!= controleert of twee waarden niet gelijk zijn aan elkaar.
! controleert of een variabele false is
  (de waarde false levert dus true op met deze operator).
< controleert of een waarde kleiner is dan een andere.
> controleert of een waarde groter is dan een andere.
<= controleert of een waarde kleiner is dan of gelijk aan een de andere.
>= controleert of een waarde groter is dan of gelijk aan een andere.
&& controleert of twee dingen true zijn.
  (wordt gebruikt in combinatie met andere controlerende operators).
|| controleert of tenminste een van twee dingen true is.
  (wordt gebruikt in combinatie met andere controlerende operators).

Deze operators hebben ook namen:
 - ! wordt NOT genoemd.
 - && wordt AND genoemd.
 - || wordt OR genoemd.

Bij controlerende opdrachten in JavaScript gelden waarden als 0, null, "" als false. Ook geen waarde geldt als false.

Een voorbeeld van het gebruik van controle-operators:
Voor meer voorbeelden: kijk ook nog eens terug naar de logische operators in de voorbeeldlussen die ik eerder gegeven heb in deze tutorial.

Wat je bij logische operators niet mag vergeten is dat ze controlerend werken:
je kunt er niets mee toekennen, maar alleen maar een waarde true of false krijgen.
Daarom moet je ook opletten dat je = en == nooit met elkaar verwart.

Er is ook een voorwaardelijke operator, namelijk ? :.
Deze operator werkt als een soort if-else-statement, maar dan alleen voor het geven van een waarde, niet voor het uitvoeren van hele opdrachten.
De syntaxis is zo:

voorwaarde ? waarde bij true : waarde bij false

Als de voorwaarde voor vraagteken true is, wordt de waarde tussen het vraagteken en de dubbele punt teruggegeven. Als de voorwaarde false is wordt de waarde achter de dubbele punt teruggegeven.
Omdat deze operator waarden teruggeeft, kun je hem dus gebruiken door een toekenning aan een variabele. Bijvoorbeeld zo:

De operators <<, >>, >>>, ~, |, &, ^ zijn bitsgewijze operators. Dit zijn operators voor het maken van binaire berekeningen. Het zijn berekeningen met enen en nullen.
Over bitsgewijze operators ga ik het in deze nu tutorial niet hebben. Omdat dit ingewikkelde, weinig gebruikte operators zijn.

Er zijn in JavaScript een aantal belangrijke statements, die eigenlijk onder speciale operators vallen, daarom bespreek ik deze kort in dit hoofdstuk. Het gaat om de operators delete, void, typeof, instanceof, in, new, this.
Met delete kun je een variabele/functie en de waarde ervan verwijderen, nadat je deze gemaakt hebt. Je zet deze operator vóór de naam van de variabele.
Met void kun je een opdracht uitvoeren zonder een waarde terug te geven (undefined is de waarde).
Met typeof kun je, zoals ik al eerder verteld heb in het hoofdstuk Variabelen, het type van een variabele zien (object, string, number, etc.). Je zet deze operator vóór de naam van de variabele.
Met instanceof kun je de constructor (een functie waarmee je een object maakt) controleren van een object. Je zet deze operator tussen de naam van het object en de naam van de constructor in.
Met in kun je van een variabele controleren of deze een eigenschap is van een bepaald object. Je zet deze operator tussen de naam van het variabele en de naam van het object in.
Met new maak je een object. Je zet deze operator vóór de naam van de constructor.
Met this kun je de naam van een object waarin je een variabele of eigenschap noemt weglaten. Je zet this op de plaats van de opject-naam.

De betekenis van de genoemde operators die met objecten en constructors te maken hebben is nog niet begrijpelijk, maar in het hoofdstuk Objecten zal het duidelijk worden.
Van de operators delete, void en this geef ik nu een paar voorbeelden.
Het volgende script geeft een fout, omdat de variabele x gewist is met delete als deze wordt aangeroepen:
Met void kun je net als met return false de werking van bepaalde events en dergelijke uitschakelen, omdat deze afhankelijk zijn van een bepaalde waarde, die standaard wordt teruggegeven. Maar alleen kan void ook worden gebruikt met javascript:, waardoor het mogelijk is dit in het href-attribuut van een link te zetten of in de adresbalk in te typen. Voorbeeld:
Klik

Deze link verandert via een javascript:-opdracht de paginatitel. Zou je niet de void-operator gebruiken in de link, dan wordt de waarde "Hallo!" van de document.title in een nieuwe pagina van de browser getoond, waardoor je van de titelverandering niet veel zal zien. Dit is logisch: het is de waarde die als doel van het href-attribuut wordt teruggegeven. Het doel van een href-attribuut in een link wordt altijd in de browser getoond. Hier is de link zonder void:
Klik

Om de teruggegeven waarde uit te schakelen hoeft er geen hele opdracht te staan achter void. Je kunt, in plaats van opdracht, ook iets neerzetten dat niets betekend, bijvoorbeeld de waarden "", 0, null, false. Je kunt echter niet helemaal niets invullen, zonder een error te krijgen, er moet altijd iets achter void staan, al is het maar een lege waarde. In het volgende script staat een nul bij void:
Klik

Deze link doet helemaal niks, geeft ook geen # als locatie, etc.

Op deze manier kun je ook een opdracht buiten de void opdracht gebruiken:
Klik

Het gebruik van haakjes bij void is overigens niet nodig als je iets hebt zonder spaties, zoals 0:
Klik

De operator this is handig. Je kunt ermee verwijzen naar het huidige object waarin je bezig bent, zonder de hele naam te noemen. Voorbeeld:
Klik

Door op de link te klikken verandert de tekst in de link. In deze link verwijst this dus naar deze link zelf.

Net als in de echte wiskunde, zijn er in JavaScript ook voorrangsregels als meerdere operators bij elkaar gebruikt. Het zijn een soort "Meneer van Dale wacht op antwoord"-regels.
Ik geef hier een schema. Bovenaan staan de operators met de hoogste rang. Onderaan staan die met de laagste rang. Als meerdere operators dezelfde rang hebben, is de regel dat ze van links naar rechts uitgerekend worden.

1 ++  -- 
 - (voor negatief getal)
  ~  !
delete  void  typeof  instanceof
 in  new  this
2 * / %
3 + -
4 << >> >>>
5 < <= > >=
6 == !=
7 &
8 ^
9 |
10 &&
11 ||
12 ?:
13 = *= -= *= /= %=

En ten slotte moet ik nog opmerken dat je natuurlijk met het gebruik van haakjes ( ), de voorrangsregels van operators kunt manipuleren, want iets wat tussen haakjes staat heeft altijd de hoogste voorrang.

Terug naar Inhoudsopgave


Strings

Strings vormen een belangrijk type waarde. Het zijn de stukken tekst, reeksen van tekens, die je heel vaak gebruikt in JavaScript.
Strings zijn objecten: ze bevatten eigenschappen en methoden. Door deze eigenschappen en methoden is het mogelijk om van alles te doen met strings.
Zoals ik al eerder uitgelegd heb, met aanhalingstekens ("" of '') kunnen we aangeven dat we een string willen maken. Maar het kan ook nog aangegeven worden met new String():
Als we vervolgens echt een waarde willen geven kunnen we dat als parameter zetten tussen de haakjes van de constructor String():
Het is echter volstrekt zinloos het zo te doen, omdat we kunnen volstaan met alleen aanhalingstekens. In andere talen, zoals Java, is het vaker nodig om duidelijk te vermelden dat het om een string gaat, maar in JavaScript hoeft dit niet.

Voor strings zijn er twee aanhalingstekens " en ', om zo meerdere aanhalingstekens binnen elkaar te kunnen gebruiken. In bijvoorbeeld HTML-tags is dit handig:
Het woord hallo kan hier niet tussen dubbele aanhalingstekens staan, omdat die al om de hele javascript:-opdracht staan. Dubbele aanhalingstekens vormen een onderbreking.
Het is mogelijk binnen dubbele aanhalingstekens enkele aanhalingstekens te gebruiken, maar ook andersom. Wat echter niet mag is een string openen met dubbele aanhalingstekens en hem afsluiten met enkele aanhalingstekens, en andersom.
Goed: "Hallo!"
Goed: 'Hallo!'
Fout: "Hallo!'
Fout: 'Hallo!"

Voor het aangeven van speciale tekens zonder dat er errors ontstaan kun je een backslash (\) gebruiken in combinatie met een teken.
Omdat nu zo ook de backslash zelf een speciaal teken is moeten we bij deze ook een extra backslash gebruiken, dus \\. Voorbeeld:
We typen voor elke backslash dus twee backslashes.
Voor het aangeven van een regeleinde kunnen we \n gebruiken:
Voor het aangeven van inspringingen, tabs, kunnen we \t gebruiken:
Bij \n en \t is het wel opletten dat je bij document.write() slechts spaties zal zien als je geen <pre>-tags gebruikt. Wil je toch regeleinden en vere inspringingen buiten <pre>-tags, dan moet je HTML-codes in de document.write()-opdracht gebruiken, namelijk <br> en &nbsp;.
Voor aanhalingstekens kunnen we óók backslashes gebruiken: \" en \'. Voorbeeld:
Klik

Om tekens in een string te vinden, of om nummers van tekens in een string te vinden, zijn er een aantal zoekmethoden in een string.
Met de methode indexOf() kun je de plek van een bepaald teken of woord in een string opzoeken. Deze plek is een nummer. Als het teken of woord dat je zoekt meerdere keren voor komt in de string waarin je zoekt string wordt standaard de eerste van dit teken of woord gezocht en daarvan het nummer gegeven. Het is echter belangrijk te weten dat de nummering van de tekens in een string niet begint bij 1, maar bij 0. Het eerste teken van een tienletterige string is dus nummer 0 en het laatste is dus nummer 9. Voorbeeld:
Dit script toont de nummers van het eerste teken (0) en het laatste teken (5) uit string txt.
Het is mogelijk vanaf een ander nummer dan 0 te zoeken naar een teken in een string. Dit geven we aan met een tweede parameter in de indexOf()-methode. Hier een voorbeeld:
De uitkomst van de zoekopdracht in dit script is 9, want dit is de eerste "a" vanaf teken 7.
Als we van achter naar voren willen zoeken naar een teken in een string, in plaats van van voor naar achteren, kunnen we de methode lastIndexOf() gebruiken. Ook bij deze methode kunnen we eventueel aan geven vanaf welk tekennummer we willen zoeken. Het volgende script lijkt op het vorige script, maar het zoekt vanaf teken 7 terug in plaats van verder:
Dit script geeft de waarde 6, want deze "a" komt direct voor de "b" op nummer 7.
Het in JavaScript ook mogelijk om juist met een tekennummer een of meer tekens uit een string te zoeken, in plaats van andersom.
Met de methode charAt() kun je een tekennummer invullen en als waarde een teken uit een string terugkrijgen die op de plek van het nummer staat. Voorbeeld:
We krijgen in dit script als waarde de letter "q".
Met de methode substring() kunnen we meerdere tekens zoeken. We kunnen een of twee parameters gebruiken. De eerste parameter geeft aan vanaf welk tekennummer we willen zoeken. Als we geen tweede parameter opgeven, worden alle tekens in de string vanaf het nummer van de wel opgegeven parameter gezocht, tot aan het einde van de string. Geven we ook een tweede nummer als parameter op, dan wordt er vanaf het nummer van de eerste parameter tot het nummer van de tweede gezocht. Let op: er wordt gezocht naar de tekens tot de het nummer van tweede parameter, niet tot een met. Voorbeeld:
Dit script toont dus de letters "klm" (nr. 10, 11 en 12) uit de string txt.

De hierboven genoemde zoek-methoden in strings zijn vooral erg handig in combinatie met elkaar. In het volgende voorbeeld wordt een bestandsnaam gezocht uit een URL:
Voor het vinden van het aantal tekens in een string bestaat er een eigenschap length. Let op: een eigenschap, dus length is zonder haakjes. Voorbeeld:
De length-eigenschap van een string kan ook goed worden gebruikt om het laatste teken van een string te vinden:
Let dus ook op bij het zoeken naar het laatste teken in een string dat de positie ervan de stringlengte min een is en niet de lengte, omdat een string begint met teken nr 0 en niet met teken nr 1. Daarom geven indexOf() en lastIndexOf() trouwens ook geen 0 terug, als de gezochte tekens niet te vinden zijn in de string, maar ze geven dan -1 als waarde terug.
En dan is er nog een methode split() waarmee een stringwaarde gesplitst kan worden teruggegeven in een array, een object met waarden in een numerieke indeling. Deze methode is de tegenhanger van de methode join() van arrays. Belangrijk om te weten van de methode split() is trouwens dat je er altijd een string als parameter aan moet meegeven. Anders wordt de string niet gesplitst teruggegeven. De parameter mag een ook lege string ("") zijn. In dat geval wordt de string gesplitst in allemaal losse letters gegeven. Maar is de stringparameter niet leeg dat wordt de string alleen gesplitst op de plaatsen waar de opgegeven parameter te vinden is. Een opdracht als "www.eduarddejong.nl".split(".") geeft dus een array bestaande uit www, "eduarddejong" en "tk" terug.
Meer over de methode split() van strings en de omgekeerd werkende methode join() van arrays vertel ik in het volgende hoofdstuk Arrays, nadat ik duidelijk gemaakt het wat arrays precies zijn en hoe we de waarden van een array op kunnen vragen.

Naast de hierboven genoemde methoden van strings, zijn er ook methoden in strings om het uiterlijk er van te beïnvloeden. Zo zijn er bijvoorbeeld de methoden toUpperCase() en toLowerCase(). De methode toUpperCase() geeft als waarde de string in hoofdletters en de methode toLowerCase() geeft de string in kleine letters. Voorbeeld (in een dialoogvenster en in de statusbalk):
Er zijn zo ook methoden strings met opmaak terug te geven, doordat deze methoden HTML-tags er omheen zetten. Deze methoden werken doordat ze HTML gebruiken dus alleen correct in een pagina zelf en niet in dialoogvensters, waarin de tags gewoon zichtbaar worden in plaats van de bedoelde opmaak.
Met de methode bold() kunnen we een string vet weergeven, de methode gebruikt <b>-tags.
Zo geeft de methode italics() cursieve tekst door <i>-tags.
De methode strike()
geeft doorgestreepte tekst door <s>-tags.
De methode big() maakt grotere tekst door <big>-tags.
De methode small() maakt kleinere tekst door <small>-tags.
De methode sup() zorgt voor superschrift door <sup>-tags.
De methode sub() zorgt voor subschrift door <sub>-tags.
Met de methode fontsize("lettergrootte") kunnen we de lettergrootte van een string bepalen (1 t/m 7). Deze methode maakt <font> tags en plaatst de opgeven lettergrootte in het size-attribuut ervan.
De methode fontcolor("kleurcode of kleurnaam") geeft kleur aan de tekst met een color-attribuut in <font>-tags die de methode toevoegt.

Voorbeeld waarin we tags zien:
Voorbeeld waarin we wel opmaak zien:

Terug naar Inhoudsopgave


Arrays

In arrays kunnen we, zoals ik reeds eerder verteld heb, meerdere waarden in een genummerde volgorde opslaan. Daarmee zijn arrays een overzichtelijke oplossing om grote hoeveelheden gegevens te sorteren. Door de nummervolgorde is het mogelijk om bijvoorbeeld met een lus dingen allemaal stuk voor stuk op te slaan in een array of juist stuk voor stuk te lezen uit een array. Arrays zijn in JavaScript even als strings objecten, omdat ze eigenschappen en methoden bevatten. Bovendien zijn de genummerde onderdelen van een array in feite óók een soort eigenschappen ervan.

Een array wordt gewoonlijk als volgt gedefinieerd: met new Array() of kortweg [ ].
Dus bijvoorbeeld zo: mijnarray = new Array();
Of bijvoorbeeld zo: mijnarray = [ ];
Bij de definiëring van een array in JavaScript hoeven we de grootte ervan niet aan te geven. We kunnen zo veel of zo weinig onderdelen in een array stoppen als we maar willen. Dit is in tegenstelling tot programmeertalen als C en Java, waarin dit wel moet. In die talen moet je van te voren aangeven hoe groot je een array wilt en je kunt er vervolgens niet foutloos meer gegevens in stoppen dan dat opgegeven getal.

De onderdelen van een array benaderen kan door de naam van het array te noemen met daarachter tussen vierkante haakjes [ ] het nummer. Hierbij is het belangrijk om te weten dat het eerste gegeven in een array niet [1] is maar [0]. Net zoals strings beginnen bij teken 0. Dit is trouwen iets wat algemeen geldt in programmeertalen. Ook in bijvoorbeeld C en Java wordt er begonnen bij 0. Begin je met een [1] array te nummeren, dan is dat niet fout, maar dan heeft het eerste gegeven uit het array alleen geen waarde.
Twee voorbeelden van een array:
Er is nog een belangrijke manier van van waarden in een array stoppen. Dat is bij de definiëring van het array zelf, door de gegevens als parameters mee te geven aan de constructor-functie Array() of aan de verkorte versie ervan ([ ]). Hier een twee voorbeelden:
Zoals te zien is in het voorbeeld blijft het opvragen van de waarden uit het array gewoon hetzelfde als in de vorige voorbeelden. Wat ook te zien is, is dat het eerste geven in een array inderdaad onderdeel 0 blijkt te zijn en het tweede onderdeel 1.

Er is nog iets bijzonders aan arrays in JavaScript, als wij dat met andere talen vergelijken: we mogen in een array alle datatypen stoppen die we willen, en dan ook binnen hetzélfde array. We kunnen in een array andere arrays opslaan, we kunnen er objecten in opslaan, we kunnen er variabelen van de typen number, string en boolean in opslaan, en we er kunnen zelfs ook nog functies in opslaan. Hier volgt daar een voorbeeld van:
Als we een array met daarin nog meer arrays hebben krijgen we een aanroep zoals inderdaad testarray[5][2] uit het voorbeeld. Zo'n array wordt een meerdimensionaal array genoemd.

Net als strings hebben arrays een eigenschap length. Met deze eigenschap kunnen we zien hoe groot het array is. Hier volgt een voorbeeld met een zeer compacte scriptvorm plus een overzichtelijke vorm:
Let weer op dat het laatste gegeven in een array, vanwege de telling vanaf 0, niet de grootte van het array is, maar de grootte min 1.
Zoals ik in het vorige hoofdstuk al verteld heb, kunnen we een string splitsen in een array met de methode split(). Hier heb ik twee voorbeelden van het gebruik van deze methode:
Arrays hebben een tegenovergesteld werkende methode join() die ze samenvoegt tot een string. Standaard is het zo dat als we een array willen weergeven als string, bijvoorbeeld met een window.alert()-opdracht dat we de onderdelen van het array gescheiden van elkaar door komma's te zien krijgen. Voorbeeld:
Willen we dit anders, dan is het zinvol de methode join() te gebruiken. We moeten dan echter wel als parameter meegeven wat we als scheidingsteken willen in plaats van de komma's. Hier een voorbeeld met een punt als scheidingsteken:
Als we als scheidingsteken een lege string opgeven worden alle array-onderdelen keurig achter elkaar geplakt:

Terug naar Inhoudsopgave


Objecten

Het begrip object heb ik al veel genoemd in deze tutorial: een variabele die binnen zichzelf eigenschappen bevat, die allemaal een waarde kunnen hebben, en methoden, die opdrachten kunnen uitvoeren. In dit hoofdstuk vertel ik nog preciezer wat objecten zijn en hoe ze in elkaar zitten. Ook vertel ik hoe we zelf objecten kunnen maken en hoe we hun objecttypen kunnen maken.

JavaScript is een objectgebaseerde taal. Dat wil vooral zeggen dat er al allerlei objecten bestaan, zoals in het volgende hoofdstuk Browserobjecten ook zal blijken. Heel veel is in JavaScript een object, want heel veel bevat eigenschappen en methoden. We hoeven zelf nog maar nauwelijks objecten te maken. Dit is ook een verschil tussen veel scripttalen en echte zelfstandige programmeertalen. Een scripttaal bevindt zich in een kant en klare omgeving met allemaal bestaande objecten. Terwijl we in echte programmeertalen, zoals C++ en Java alle objecten zelf moeten maken. Er zijn in die talen wel heel veel objecttypen ingebouwd (die dan klassen heten) en kunnen we daar ook veel meer mee dan in JavaScript. In wat oudere programmeertalen, zoals Pascal en C, komen objecttypen en objecten echter nog niet voor, maar kennen we gewoon alleen variabelen en functies. Programmeertalen als C++ en Java, die volledig gericht zijn op het maken van klassen en objecten, worden objectgeoriënteerde talen genoemd.

Toch kunnen we ook in in JavaScript een beetje objectgeoriënteerd programmeren. We kunnen op een versimpelde manier ook objecten maken. Dat is mogelijk met behulp van een objecttype. Een objecttype zelf wordt gemaakt met een functie. Zo'n functie wordt een constructor of ook wel objecttypedefinitie genoemd. Constructors kunnen ingebouwd zijn in JavaScript. Voorbeelden hiervan zijn de functies String(), Array() en natuurlijk Object(). We kunnen ze ook zelf maken. Zelfgedefinieerde objecttypen zijn echter altijd automatisch afgeleid van het type Object().
Het maken van een object met het gebruik van een constructor wordt instantiëren genoemd. En de aanroep van zo'n constructor om er een object van te maken heet een instantie. Om een functie te instantiëren, in plaats van deze normaal aan te roepen, moeten we gebruik maken van de operator new. In deze tutorial zijn al voorbeelden geweest van instanties, namelijk de opdrachten new String(), new Array().
Hier volgt een voorbeeld van een zelfgedefinieerde constructor en een daarvan afgeleide instantie:

Natuurlijk is het pas zinvol om een objecttype te maken als we eigenschappen en methoden definiëren. Zoals ik al eerder uitgelegd heb zijn eigenschappen van een object gewoon variabelen en zijn methoden van een object gewoon functies. Om ze in een object te krijgen kunnen we variabelen en functies in een constructor plaatsen met het woord this. In het hoofdstuk operators heb ik verteld dat this altijd naar het huidige object verwijst waarin je werkt. In dit geval is dat dus het object dat je instantieert van de constructor. Gebruik je geen this in de functie dan definieer je geen eigenschap of methode, maar gewoon een normale variabele of functie. Hier volgt een voorbeeld van een constructor waarin eigenschappen en methoden gedefinieerd worden en een daarvan vervolgens geïnstantieerd object:
Het maken van een constructor is vooral handig als we meerdere objecten van hetzelfde type willen. Zo kunnen we objecten ook gebruiken om een aantal dingen te beschrijven van een bepaald type, bijvoorbeeld gereedschap. We kunnen beschrijven hoe het gereedschap er uitziet (de eigenschappen) en hoe het werkt (de methoden). Het is nu handig om parameters te gebruiken in de constructor die we gereedschap zullen noemen. Hier volgt het voorbeeld:

Naast die complexe manier van objecten maken kan het ook veel simpeler. Je kunt een constructor namelijk bijvoorbeeld ook direct bij de definiëring er van al aan een object plakken. Wat we tot nu toe steeds deden is zoiets als dit:

function Objecttype1()
{
    // Hier komen eigenschappen en methoden.
}
object1 = new Objecttype1();
object2 = new Objecttype1();

Maar als je geen parameters gebruikt kun je het dus net zo goed zo doen:

object1 = new function Objecttype1()
{
    // Hier komen eigenschappen en methoden.
};
object2 = new Objecttype1();

Of zelfs zo:

object2 = object1 = new function Objecttype1()
{
    // Hier komen eigenschappen en methoden.
};

Je kunt dan ook best volstaan met een anonieme constructor:

object2 = object1 = new function()
{
    // Hier komen eigenschappen en methoden.
};

In JavaScript hoef je eigenschappen en methoden zelf helemaal niet allemaal in een constructor te definiëren. Je kunt ze ook allemaal later nog toe voegen aan een object. Hier volgt een voorbeeld, met een anonieme constructor die zelf helemaal leeg is:
En zelfs dit kan nog eenvoudiger, want die lege anonieme constructor (function(){}) is onzin: je kunt in plaats hiervan ook de ingebouwde constructor Object() gebruiken om aan te geven dat je variabele een object moet zijn. Voorbeeld:
Ten slotte de kortste schrijfwijze: je kunt op een vergelijkbare manier als bij arrays de gegevens opsommen tussen haakjes, namelijk tussen accolades { }. Hier de syntaxis:

mijnobject =
{
    gegeven1:waarde1, gegeven2:waarde2, gegeven3:waarde3, etc.
}

Voorbeeld:
Kortom, er zijn vele manieren om objecten te maken.

Eigenschappen van objecten kunnen zelf ook objecten zijn. Dit kan als er aan eigenschappen instanties worden toegekend. Maar ook gewoon als het strings of arrays zijn, want deze hebben, zoals eerder verteld, ook verschillende eigenschappen en methoden. Zo kun je dus al snel een soort boomstructuur van objecten krijgen en zou je bijvoorbeeld namen kunnen krijgen als object1.object2.eigenschap1.length of misschien wel nog langer.

De aanroep van eigenschappen en methoden uit een object kan, zoals we steeds zien, met een punt. Er is in JavaScript echter nog een tweede manier om eigenschappen en methoden aan te roepen. Het kan namelijk ook in een array-notatie, waarbij we dan tussen de vierkante haakjes [ ] geen nummer opgeven, maar de naam van de eigenschap of methode als een string:

In JavaScript is een voor elk datatype (behalve undefined) ook een objecttype:
Voor object is er de constructor Object().
Voor string is er de constructor String().
Voor number is er de constructor Number().
Voor boolean is er de constructor Boolean().
Voor function is er de constructor Function().

Maar zoals we in dit hoofdstuk gezien hebben zijn er binnen het datatype object ook nog specifiekere objecttypen. Er is voor arrays een constructor Array(), terwijl arrays onder het datatype object vallen (array als datatype bestaat niet). Bovendien zijn er bijvoorbeeld ook nog de constructors Date() en Image(), waarover ik het later in deze tutorial nog heb. Ook hiervan zijn de instanties van het datatype object. En alle volledig zelfgemaakte objecten, van zelf geprogrammeerde constructors, zijn dus altijd van het datatype object.
Strings hebben ook eigenschappen en methoden, maar zijn, in tegenstelling tot arrays en alle andere objecten, geen object-variabelen en vallen onder een eigen datatype string.
We kunnen vanwege al die constructors dus elk datatype ook via instantiëring gebruiken. Je kunt bijvoorbeeld x = true ook definiëren als x = new Boolean(true) en i = 10 als i = new Number(10).

Terug naar Inhoudsopgave


Browserobjecten

Wanneer we JavaScript programmeren in een webpagina, hebben we al gauw te maken met objecten die onderdeel van de browser of van de webpagina zijn. Voor een groot deel zijn dit zichtbare elementen of kenmerken. Het gaat dan om precies te zijn om het webdocument waarin we werken, of om het venster/frame waarin deze geladen is, of het gaat om de HTML-elementen die we gemaakt hebben. Met al deze objecten kunnen veel doen in JavaScript. Hierover gaat dit hoofdstuk dan ook.

Het belangrijkste object is het object window, het object dat het venster vertegenwoordigd waarin de pagina geladen is. In JavaScript zijn alle objecten, variabelen, functies, die we zelf maken en die al bestaan, automatisch onderdeel van dit object. Daarom mogen we voor alles in principe window. schrijven. Maar het noemen van het window-object is echter niet verplicht. Als we een variabele definiëren die x heet, mogen we deze ook aanroepen als window.x, en andersom geld dat als een variabele window.x definiëren, dat we deze ook als x mogen aanroepen. Hetzelfde geldt ook voor functies. Een voorbeeld:
Elke variabele die niet is gedefinieerd is in een object of in een constructor daarvan is dus wel een eigenschap van het window-object en elke functie die niet is gedefinieerd is in een object of in een constructor daarvan is dus wel een methode van het window-object. In feite is daarom elke variabele een eigenschap, is elke functie een methode, en is er dus geen echt verschil tussen. Dit geld dus ook voor het window-object zelf: het is een eigenschap van zichzelf. Daarom mag je window ook window.window noemen, of window.window.window, enzovoorts. En bijvoorbeeld zou je de alert()-methode dus probleemloos window.window.window.alert() kunnen noemen.

Er is nog een speciaal kenmerk van het window-object: het heeft meerdere vormen, met eigen namen. Dit is namelijk belangrijk als we werken met frames, de verschillende subpagina's binnen een hoofdpagina die we definiëren met <frameset>-tags en <frame>-tags. Tegenwoordig kunnen we bovendien ook inline-frames, binnen een body, definiëren een met <iframe>-tags. In plaats van het standaard window kunnen we dan de namen van de frames gebruiken met JavaScript om te verwijzen naar het window-object in die frames en alles wat daar onderdeel van is. En bovendien hebben we daarbij ook net als in HTML zelf vaste namen als self, parent en top. Alleen let wel op het feit dat je in JavaScript geen underscore (_) voor deze namen moet zetten, dus geen _self, _parent en _top schrijven maar self, parent en top. Het object self verwijst naar het huidige frame waarin de pagina met je script geladen is en is daarom synoniem voor het gewone object window zelf. Het object parent verwijst naar een bovenliggende framepagina van de huidige pagina. En top verschilt van parent wanneer we meerdere framepagina's binnen elkaar hebben: het verwijst altijd naar het hoogste frame.
Als we parallelle pagina's naast elkaar hebben geladen binnen een hoofdpagina en we willen vanuit een frame een ander frame aanspreken, dan moeten we altijd eerst naar de hoofdpagina verwijzen met parent (of als het kan, mag top ook), om vandaar uit de naam van het andere frame te noemen of met het frames-array te verwijzen naar het andere frame. Je krijgt dan aanroepen zoals bijvoorbeeld parent.frame1, wanneer het aan te roepen frame frame1 heet, of aanroepen als parent.frames[0], wanneer we het eerste frame willen aanspreken uit de hoofdpagina. parent.frames["frame1"] en parent.frames.frame1 zijn ook mogelijk. Hier volgt een voorbeeld waarbij de inhoud van een frame bepaald wordt door een script in een ander frame.
De hoofdpagina, die we opslaan als "mainpage.html":
De pagina met het JavaScript erin, die we opslaan als "contentpage.html":
Merk ook op dat het met JavaScript dus mogelijk is complete pagina's te genereren, doordat je net zoveel tekst en HTML kwijt kunt in een string als je maar wilt.

Naast de sturende werking in HTML-frames, biedt JavaScript ook veel mogelijkheden met popupvensters, die met de window.open()-methode geopend worden. De methode window.open() heeft drie belangrijke parameters.
De eerste parameter bepaalt de locatie van de pagina in het geopende venster. Als in deze parameter een lege string gezet wordt, wordt er een lege pagina geopend. We kunnen echter net als bij frames ook met een document.write()-opdracht tekst en HTML in de pagina van het venster zetten.
De tweede parameter bepaald de framenaam van het venster. Als we een lege string in vullen heeft het popupvenster geen naam. Geef je wel een naam op dan kun je als met deze naam als target van een link een pagina in het venster tonen. Ook kun je met een nieuwe window.open()-opdracht dan een nieuwe pagina tonen in hetzelfde popupvenster. Hier een voorbeeld van een link die met window.open() steeds opnieuw een venster opent wanneer er op geklikt wordt omdat de naam ontbreekt, of er nou al een venster geopend is of niet:
Venster openen

En nu een voorbeeld van een link die één keer een een venster opent wanneer die nog niet gebeurd is en die daarna alleen nog maar de pagina opnieuw opent in het bestaande venster, omdat er een naam ("mijnsite") aan het venster gegeven wordt:
Venster openen

Zo'n naam geven aan een venster kan dus bijvoorbeeld het voordeel hebben dat de bezoekers van je website niet gek worden van het aantal popupvensters als je steeds nieuwe URL's wilt openen.
De derde parameter is een string waarin een hele serie van opties gezet kan worden gescheiden door komma's. Aan de opties in deze string kun je iets toekennen via een is-teken =. Ze bepalen het uiterlijk van het geopende venster, dat standaard gewoon een normaal venster is met alles er op en er aan. Hier volgen de opties en wat er aan toe gekend wordt:

width - een nummer dat breedte van het venster in pixels instelt.
height - een nummer dat breedte van het venster in pixels instelt.
left - een nummer dat horizontale positie van het venster in pixels instelt.
top - een nummer dat verticale positie van het venster in pixels instelt.

resizable - steld in of venster het veranderbaar van grootte is.*
scrollbars - steld in of het venster scrollbalken heeft.*
status - steld in of het venster een statusbalk heeft.*
menubar - steld in of het venster een balk met menu's heeft.*
toolbar - steld in of het venster een balk met knoppen heeft.*
location - steld in of het venster een adresbalk heeft.*
directories - steld in of het venster een balk met koppelingen heeft.*

* 1 of yes schakelt deze opties in. 0 of no schakelt ze uit. Het alleen noemen van de opties, zonder waarde, schakelt de ze ook in.

Belangrijk om te weten is dat als er ook maar één van de bovenstaande opties gebruikt wordt in een window.open()-opdracht dat alle andere opties automatisch uitgeschakeld worden en er daardoor een kaal popupvenster gemaakt wordt en geen standaard volledig browservenster meer. Om de opties dan nog in te schakelen moet je ze dus stuk voor stuk noemen in de parameterstring.
Hier volgt een voorbeeld met een opgegeven grootte en positionering en ingeschakelde scrollbalken, maar wat zal opvallen is dat de andere opties van het venster daarbij automatisch uitgeschakeld staan:
Venster openen

Zo kun je met JavaScript dus hele mooie vensters maken.
Internet Explorer ondersteund zelfs nog een extra optie: fullscreen, waarmee een volledige schermweergeve getoond kan worden.
Het enige probleem is dat popupvensters, bij misbruik door bijvoorbeeld een site met tientallen reclamepopups te maken, ook zeer irritant kunnen zijn. Om deze reden hebben vrij veel mensen de window.open()-methode geblokkeerd. En daarom zal er dus een niet erg groot publiek van je website kunnen genieten als deze volledig gebaseerd is op een mooi gebruik popups, wanneer je er niet duidelijk bij vermeld dat mensen deze niet moeten blokkeren op je website.

Als je een popupvenster een naam geeft dan is het echter niet zo dat je, zoals we net bij frames wel deden, de naam van het venster kunt aanroepen als een soort window-object. Als je dus bijvoorbeeld window.open("", "mijnsite", "width=700,height=450,scrollbars") doet, dan kun je daarna niet zoiets doen als mijnsite.location.href = "http://www.eduarddejong.nl". Je kunt dit wel op een andere manier oplossen. De window.open()-methode geeft namelijk als waarde het window-object van het popupvenster dat je opent terug. Daarom kun je een aanroep van window.open() prima toekennen aan een variabele, die dan dus als window-object van het popupvenster functioneert. Om dezelfde reden kan het ook nog korter: je mag gewoon window.open("", "mijnsite", "width=700,height=450,scrollbars").location.href = "www.eduarddejong.nl" doen, of bijvoorbeeld window.open("", "mijnsite", "width=700,height=450,scrollbars").document.write("Hallo!"). Dit is wat ik al het hoofdstuk Basis verteld heb. Hoewel het overigens beter is om, zoals ik ook al heb verteld in dat hoofdstuk, om na document.write() in de popup ook nog document.close() te gebruiken. Maar dan moet window.open() dus eerst worden toegekend aan een variabele. Een voorbeeld ervan:
En ten slotte is er ook nog een manier om het window.object van het browservenster dat een popupvenster geopend heeft aan te spreken vanuit dat popupvenster. Dit kan met opener. Als je vanuit een popupvenster bijvoorbeeld de locatie van het hoofdvenster wilt veranderen, kun je dus opener.location.href gebruiken.

Met het window.location-object kunnen we, zoals ik al verteld heb in het eerste hoofdstuk, locatie in de browser bepalen. Het kan om precies te zij met location zelf of met de href-eigenschap ervan. Maar er kan nog iets meer met dit object, waarover ik dan ook iets wil vertellen.
Met de methode location.reload() kunnen we de huidige pagina vernieuwen, herladen.
Met de methode location.replace("nieuwe pagina.html") kunnen we een nieuwe pagina laden, zoals met href, maar dan wel met het verschil dat de huidige pagina vervangen wordt in de geschiedenis van de browser. Je kunt via de browserknop "vorige" of "back" niet meer terug vanuit de nieuwe pagina naar de vorige pagina, maar je zult dan naar de pagina daarvoor gaan, als deze er is. Deze methode is handig als je de bezoekers van je pagina automatisch door wilt sturen naar een nieuwe en je daarbij dan wilt dat de bezoekers van de pagina niet opnieuw doorgestuurd worden wanneer zij op de knop naar "vorige" / "back" klikken, als ze terug willen naar de pagina die ze voor de doorstuurpagina bezochten. Er is weinig op het internet zo vervelend als geen vorige kunnen kiezen omdat je dan klik-klik weer opnieuw doorgestuurd wordt, terwijl dit dus voorkomen kan worden met location.replace().
Met de eigenschap location.search kunnen we de zogeheten querystring van de URL zien, indien deze er is. De querystring van een URL is de informatie die achter een vraagteken (?) in de url kan staan. Dit zijn meestal gegevens die op de webserver van een pagina geïnterpreteerd worden. Maar het is ook in JavaScript dus mogelijk om informatie van de querystring te zien door location.search te gebruiken. Zo kun je ook informatie tussen verschillende pagina's uit wisselen.

Een ander object is het object window.history. We kunnen ermee de werking van de knoppen "vorrige" / "back" en "volgende" / "forward" uitvoeren. Met history.back() ga je naar de vorige pagina, als deze er is. Met history.forward() ga je verder, indien dit kan. Met een wat nieuwere, niet door hele oude browserversies ondersteunde methode history.go(paginanummer) kunnen we het aantal pagina's kiezen dat we terug willen gaan of verder willen gaan in de geschiedenis. Deze methode gaat met een negatief getal terug en met een positief getal verder. Als je history.go(-1) doet, doe je dus hetzelfde als met history.back(). En history.length ten slotte geeft de grootte van de geschiedenis weer.

Als we wat informatie willen hebben over de browserversie van de bezoeker van een pagina, bijvoorbeeld om een script daar aan te passen met if-else-controles, kunnen we het object window.navigator gebruiken:
 - de eigenschap navigator.appName geeft de browsernaam.
 - de eigenschap navigator.appVersion geeft de versie.
 - de eigenschap navigator.appCodeName geeft de codenaam.
 - de eigenschap navigator.userAgent geeft de codenaam plus de versie.
 - de eigenschap navigator.cookieEnabled geeft aan of cookies gebruikt kunnen worden.
 - de methode navigator.javaEnabled() geeft aan of Java-ondersteuning ingeschakeld is.
 - de eigenschap navigator.platform geeft de codenaam van het besturingssysteem.
 - de eigenschap navigator.userLanguage geeft de systeemtaal.
 - de eigenschap navigator.cpuClass geeft het processortype van de computer.
Overigens is het object navigator niet heel betrowbaar, als je echt precies de browser wilt weten van de bezoeker, met name omdat Firefox de naam en versie van Netscape teruggeeft en Opera de naam en versie van Internet Explorer teruggeeft. De eigenschappen appName en appVersion dienen dan ook meer om het JavaScript-type van de browser te zien. Firefox heeft dezelfde JavaScript-ondersteuning als Netscape. En het JavaScript van Opera lijkt wat op dat van Internet Explorer. Om het JavaScript-type van een browser te zien kun je echter ook simpelweg controleren welke dingen er ondersteund worden. Vaak wordt het object document.all gebruikt om te kijken welk JavaScript er ondersteund wordt. Internet Explorer en Opera hebben dit object, Netscape en Firefox niet. Maar een echt nauwkeurige controle kun je het beste krijgen door gewoon iets te controleren wat met je script zelf te maken heeft. Als je bijvoorbeeld met events werkt, kijk je dus gewoon of er een event-object is of niet. Het navigator-object is dan niet nodig. Daarvan heb ik al een voorbeeld gegeven in het hoofdstuk Events.
Een goed script werkt in iedere browser met JavaScript-ondersteuning.

Het object window.document is het grootste object binnen window. Het is de pagina die in de browser geladen is. Alle HTML-elementen behalve frames zijn er onderdeel van. Daarnaast bevat het object veel eigenschappen van de pagina, zoals kleurinstellingen en andere opmaak. De objecten waarover ik vanaf nu verder vertel in dit hoofdstuk zijn allemaal onderdeel van dit object.

Een aantal belangrijke kenmerken van een webpagina zijn te wijzigen met de volgende eigenschappen van document:
document.title - de paginatitel.
document.bgColor - de achtergrondkleur.
document.fgColor - de tekstkleur (foreground-color).
document.linkColor - de kleur van een onbezochte link.
document.vlinkColor - de kleur van een bezochte link.
document.alinkColor - de kleur van een active link.

Er zijn ook een aantal belangrijke pagina-eigenschappen in het object document.body, de JavaScript manier om body-element van een HTML-pagina de benaderen:
document.body.background - de achtergrondafbeelding.
document.body.bgProperties - het type achtergrondafbeelding, "scroll" of "fixed".
document.body.clientWidth - de breedte van de pagina in pixels.
document.body.clientHeight - de hoogte van de pagina in pixels.

En verder zijn bijna alle eigenschappen die onderdeel zijn van allerlei HTML-elementen, ook van document.body, beschikbaar in JavaScript. Hier volgen er een paar belangrijke:
tagName - de naam de de tag, het type van een element.
name - het name-attribuut, de naam, van een element.
id - het id-attribuut, het ID, van een element.
title - het title-attribuut van een element.
innerHTML - de tekst en HTML in een element.
innerText - de tekst in een element.
style - het style-attribuut, met alle CSS-instellingen van een element.
Van afbeeldingen en dergelijke is bovendien ook de src aan te roepen. En van bijvoorbeeld links kunnen we het href-attribuut benaderen.

De aanroep van HTML-elementen kan op verschillende manieren, maar niet alle manieren worden door elk element ondersteund.
Veel HTML-elementen ondersteunen het om ze met hun in het name-attribuut ingevulde naam aan te roepen.
Verder zijn er verschillende objecten die een serie HTML-elementen bevatten. Die objecten zijn als array te gebruiken en als normaal object. Voorbeelden hiervan zijn:
document.links - alle a-elementen met een href-attribuut.
document.anchors - alle a-elementen met een name-attribuut.
document.forms - alle form-elementen.
document.images - alle image-elementen.
document.embeds - alle embed-elementen (geluiden enz.).
document.applets - alle applet-elementen (Java).
document.objects - alle object-elementen (Flash enz.).
document.scripts - alle script-elementen (JavaScript en VBScript).

Hier volgt een voorbeeld vier verschillende aanroepen van een formulier, die allemaal de tekst en HTML eruit tonen:
Overigens is het zo, dat als er meerdere elementen met dezelfde name voorkomen, dat er dan automatisch een array ontstaat die deze naam zal hebben en waarin de elementen dan in de volgorde waarin ze voorkomen genummerd staan.
En verder kun je vanuit een een event-handler in een HTML-tag met this naar het element zelf verwijzen. Hiervan gaf ik al een voorbeeld in het hoofdstuk operators, waar ik de betekenis van this uitlegde.
Naast de genoemde manieren om HTML-elementen aan te roepen zijn er is er ook nog het object document.all, dat ook zowel een numeriek array als een gewoon object is. Het is een object dat alle HTML-elementen in een pagina omvat. Met dit object kun je elementen aanroepen in numerieke volgorde en bij hun naam. Je kunt ze echter ook aanroepen bij hun ID, de opgegeven naam in het id-attribuut van een tag.
Hier een voorbeeld met vijf verschillede aanroepen van de waarde van het href-attribuut uit een link, via nummervolgorde, naam en ID:
Het nadeel van het document.all-object is dat het, zoals ik al eerder verteld heb, niet bestaat in Netscape en Firefox, maar alleen in Internet Explorer en Opera.
Maar gelukkig is er tegenwoordig een andere oplossing, die wel door alle moderne browsers wordt ondersteund, namelijk de object teruggevende methode document.getElementById(), waarmee ook alle elementen uit een pagina kunnen aanroepen bij hun ID (niet bij hun naam).
Verder hebben we een methode document.getElementsByName() die een array teruggeeft van alle HTML-elementen met de als parameter opgegeven naam.
En tenslotte is er nog de methode document.getElementsByTagName() die een array teruggeeft met alle elementen van de als parameter opgegeven tagnaam.
Hier een voorbeeld van het gebruik van deze methodes:

Een voorbeeld een belangrijke functionaliteit van JavaScript is controle op ingevulde gegevens in formulieren uitvoeren, voordat deze worden verzonden naar een webserver. Dit kan door deze waarden de lezen vanuit JavaScript en dan te kijken of ze kloppen. Wanneer ze niet in orde zijn is het op een eenvoudige manier mogelijk om het verzenden van de gegevens tegen te houden. In het hoofdstuk events heb ik reeds de event-handlers onsubmit en onreset genoemd, waarmee we kunnen reageren op handelingen van de bezoeker van een pagina met een formulier. Ook heb ik verteld dat het, door met return de booleanwaarde false terug te geven in een event-handler, mogelijk is de werking van een event uit te schakelen.
Om gegevens uit een formulier bij de naam aan te roepen moet je ook de naam van het formulier aanroepen (geef het formulier dus inderdaad een naam), omdat de elementen in een formulier eigenschap zijn van het formulier. Een tekstvak dat "adres" heet en in een formulier staat met de naam "form1" kun je dus bijvoorbeeld aanroepen met document.form1.adres of document.forms.form1.adres. Binnen een formulier bestaat er echter ook een object/array met alle onderdelen uit het formulier, dat elements heet. Daarom kan "addres" ook worden aangeroepen met bijvoorbeeld document.form1.elements.adres, of als je van erg lange namen houdt kun je ook document.forms["form1"].elements["adres"] gebruiken, enzovoorts.
Om uit een formulierelement de waarde te krijgen roep je de eigenschap value ervan aan, dat hetzelfde is als het gelijknamige attribuut in de HTML-tag van zo'n element.
Hier volgt een voorbeeld van een script dat onder andere het verzenden van het formulier tegenhoud of toestaat met boolean-return-waarden, afhankelijk van of alle gegevens ingevuld zijn:

Wanneer de gegevens compleet zijn wordt dit getoond met een dialoogvenster en zal de browser ze daarna proberen te verzenden. We krijgen als het goed is dan de foutmeldig dat de (verzonnen) doellocatie "http://www.eenwebserver.com/cgi-bin/perlscript1.cgi" niet vindbaar is. Als de gegevens niet compleet zijn krijgen we dat te zien in een dialoogvenster en blijven we gewoon op dezelfde pagina. En als je het formulier wilt leegmaken wordt via onreset om bevestiging gevraagd (dit werkt met de teruggeven booleanwaarde van window.confirm()).
Zouden we de gegevens echt willen verzenden naar een URL, dan moeten we een script of programma hebben op de webserver dat de gegevens kan verwerken. Ze worden verzonden onder "naam", "adres" en "postcode". Dit heeft natuurlijk alleen zin als het programma/script op de webserver zoekt naar deze namen. We zouden het dan zelf moeten schrijven. Zo'n zogeheten CGI-programma kan worden geprogrammeerd in de scriptaal Perl of in een programmeertaal waarin je programma's van EXE-formaat schrijft, zoals C en C++. Tegenwoordig worden echter steeds vaker ook speciaal voor serverdoeleinden ontwikkelde script-talen als PHP en ASP gebruikt. Deze talen hebben het voordeel boven de klassieke CGI-talen dat ze in een gewone webpagina ingevoegd kunnen worden als script. Alleen de extensie van de pagina is anders: geen .html, maar .php of .asp / .aspx. Maar Perl-scripts en C-programma's staan in aparte bestanden, in een eigen directory die meestal "cgi-bin" heet, los van alle HTML-bestanden.
Soms wordt ook een speciale vorm van JavaScript gebruikt voor server-side opdrachten, waarover ik nog wat vertel in het hoofdstuk ActiveX.

Naast al die controles, kunnen we JavaScript zelf ook opdrachten laten uitvoeren in formulieren. JavaScript kan formulieren verzenden en wissen. JavaScript kan de tekst in tekstvakken selecteren of gewoon de tekstcursor er inzetten.
Voor het verzenden hebben formulieren methode submit() en voor wissen reset(). Zo kunnen we dus ook gewoon links met een JavaScript-opdracht gebruiken om een formulier te besturen in plaats van die standaard submit- en reset-knop. En bovendien is het prettig als bij het laden van een pagina de cursor al automatisch in een tekstvak wordt gezet wanneer je als bezoeker van de pagina iets in wil vullen. En soms kan het handig zijn een tekst te selecteren wanneer de bezoeker van een pagina alles snel wil kunnen wissen of juist wil kunnen kopiëren uit een tekstvak.
Voor het plaatsen van de cursor kunnen we de methode focus() van een element gebruiken.
Voor selecteren hebben elementen methode select().
Met de methode blur() van een element kunnen we de cursor juist uit een tekstvak weghalen.
Knoppen en links hebben een methode click() waarmee er automatisch opgeklikt kan worden.
Hier volgt een voorbeeld met drie van deze methoden:
Overigens kunnen de methoden focus() en blur() ook dienen voor de algemene "focus" in een browser, in plaats van alleen voor de tekstcursor. Je kunt er zo ook mee bepalen welk venster op de voorgrond zichtbaar is. Alleen neem je dan de focus() of blur() het window-object. Als je dus bijvoorbeeld van een popup een popunder wilt maken kun je window.focus() doen om het op de achtergrond te krijgen en het hoofdvenster van de browser te tonen. Maar je kunt ook juist de focus opnieuw op een popup-venster zetten na bijvoorbeeld het laden van een nieuwe pagina erin, om zo te zorgen dat de bezoeker van de nieuwe pagina in het venster niet over het hoofd ziet.

Vanuit JavaScript is het dus mogelijk om alle HTML-elementen te benaderen. Maar het is nog mooier: we kunnen ook CSS aanspreken vanuit JavaScript. CSS, ook wel gewoon aangeduid als "style-sheets", is een taal die complex in elkaar zit. Je kunt het extern in een aangeroepen CSS-bestand plaatsen. Verder kun je het binnen <style>-tags plaatsen. Maar ook kun je het in een style-attribuut in HTML-elementen plaatsen. Binnen een externe code en tussen <style>-tags bied CSS ook nog eens verschìllende manieren om dingen in te stellen: je kunt het voor een bepaalde taggroep instellen, je kunt het voor alle elementen met een bepaalde class-naam instellen, en je kunt het per ID instellen.
CSS maakt het met heel veel verschillende instellingen, "properties", mogelijk om veel meer en veel nauwkeuriger opmaak te geven aan een pagina dan met alleen HTML-mogelijk is.
Zo kunnen we bijvoorbeeld een lettergrootte op de pixel precies instellen, terwijl we met gewoon HTML uit slechts zeven formaten kunnen kiezen. En we kunnen bijvoorbeeld dingen op een pagina positioneren waar wij ze willen, ook op de pixel precies. CSS heeft veel mogelijkheden en precisie toegevoegd die er in HTML ontbraken.
In JavaScript kunnen we van een HTML-element het style-attribuut aanroepen. Het is dan een heel groot object waar alle CSS-instellingen uit een HTML-element eigenschap van zijn. Het verschil met de schrijfwijze van CSS zelf is vrij eenvoudig. In CSS stellen we bijvoorbeeld een lettertype in op Arial met "font-family: arial;". In JavaScript kunnen we echter geen streepje gebruiken om een naam van iets aan te roepen, want het is al een operator. Daarom wordt "font-family" in JavaScript geschreven als fontFamily. Dit werkt ook zo met alle andere CSS-properties: we gebruiken geen streepje, maar in plaats daarvan een hoofdletter.
En in plaats van een dubbele punt gebruiken we in JavaScript gewoon een is-teken =, zoals we aan alle andere eigenschappen in JavaScript ook een waarde geven.
Hier volgen twee voorbeelden waarin we een HTML-element van CSS-opmaak voorzien, eerst in CSS zelf, daarna met JavaScript:
Het leuke van de JavaScript-manier is hierbij is natuurlijk dat je er iets mee kunt doen. Je kunt de opmaak bijvoorbeeld instelbaar maken, zoals in deze ik in deze tekstopmaak-toner gedaan heb:

Naast dingen als tekstopmaak kunnen we met CSS nog meer: we kunnen werken met zogeheten layers, lagen, elementen die "zweven". Dit is mogelijk met dynamische positionering.
Standaard zijn elementen statisch gepositioneerd. Dat wil zeggen dat de elementen een vrij vaste plaats in een HTML-document hebben die hooguit links uitgelijnd, gecentreerd, of rechts uitgelijnd kan zijn, of een plaats die bepaalt is door een roosterstructuur van een een tabel. In een tabel is er dan ook een verticale indeling in boven, midden en onder uitlijnen, maar met dit alles hebben we de perfectie dan echt gehad. Een tweede belangrijk kenmerk van statische positionering is dat alle elementen voor elkaar wijken. Ze zijn gewoonlijk achter elkaar geplaatst in de volgorde waarin ze staan in de broncode. Ze overlappen elkaar nooit. Het tussenvoegen van een element zal altijd als resultaat hebben dat de andere opschuiven.
Als we echter een dynamische positie geven aan elementen kunnen we er veel meer mee. We kunnen een element met zo'n positionering precies plaatsen waar we willen, door een horizontale pixel- of procentwaarde op te geven en een verticale. En we kunnen elementen zo wel over elkaar heen plaatsen als we dit willen.
Er zijn twee soorten dynamische positionering, namelijk absolute en relatieve positionering. Bij absolute positionering geven we een horizontale waarde op vanaf een zijkant van de pagina, en een horizontale waarde vanaf de boven- of onderkant van de pagina. Bij relatieve positionering geven we de horizontale en verticale positie op ten opzichte van hoe het element in de normale, statische positie geplaatst zou zijn.
De CSS-property die we gebruiken om de positionering aan te geven is simpelweg "position". Als waarde kunnen we dus opgeven "static", "absolute" en "relative".
Wanneer we een absolute of relatieve positionering hebben kunnen "left", "top", "right" en "bottom" gebruiken voor het opgeven van de uitlijning:
 - "left" is voor de horizontale uitlijning vanaf links.
 - "top" is voor de verticale uitlijning vanaf boven.
 - "right" is voor de horizontale uitlijning vanaf rechts.
 - "bottom" is voor de verticale uitlijning vanaf onder.
Met "z-index" kunnen voor overlapping instellen in hoeverre een element op de voorgrond zichtbaar is. Hoe hoger de "z-index" waarde van een element, des te meer het element voor andere elementen zichtbaar is.
Hier volgt een voorbeeld twee een absoluut gepositioneerde teksten, met twee verschillende kleuren, zodat het duidelijk te zien is dat ze elkaar overlappen:
Met layers kun je hele leuke dingen doen in JavaScript. Bijvoorbeeld als we terugdenken aan het hoofdstuk Events waarin ik uitlegde dat we met clientX en clientY van het event-object de horizontale en verticale muispositie kunnen zien. Ook is duidelijk geworden dat we de event-handler onmousemove kunnen gebruiken om op elke muisbeweging te reageren. Met deze dingen kunnen we dus constant de muispositie bij houden. Als we nu eens deze positie steeds geven aan een layer, dan krijgen we een layer naast die de muis blijft. In de layer kunnen we bijvoorbeeld de positie van de muis tonen, via de innerHTML-eigenschap. Hier de uitvoering van het idee:

Terug naar Inhoudsopgave


Overige objecten, objecttypen en functies

Naast wat er met de browser en de webpagina te maken heeft, zijn er ook nog een aantal andere belangrijke dingen in JavaScript om te leren kennen. Over deze dingen gaat dit hoofdstuk.

In JavaScript bestaat er een mogelijkheid om na een bepaalde tijd een opdracht uit te voeren, in plaats van meteen. En bovendien is het ook mogelijk om dit steeds opnieuw te doen, zodat we een lus krijgen, die niet in een keer door gaat, maar om een bepaalde tijd. En het is vervolgens ook mogelijk zo'n timer uit te schakelen na deze gestart te hebben.
Om na een bepaalde tijd een opdracht uit te voeren kunnen we de functie setTimeout() gebruiken. We geven twee dingen mee aan de functie, namelijk de opdracht, geschreven in een string (let dus op het gebruik van een codes met een \ wanneer dit nodig is), en we geven de tijd mee in milliseconden, het aantal seconden keer duizend dus.
Hier volgt een voorbeeld met een link, waarbij JavaScript 5 seconden na er op te klikken reageert met een bericht:
Klik!

Als je meerdere keren klikt worden er meerdere timers gestart en zullen er dus meerdere vensters verschijnen.
We kunnen de timer toekennen aan een variabele. Als we dat doen kunnen we de timer ook weer uitschakelen door clearTimeout() te gebruiken. Als parameter geven we de timer mee aan deze functie. Op deze manier zouden we kunnen zorgen dat, wanneer er al een timer is, we de bestaande timer uitschakelen voor we een nieuwe starten. Aan de timer zelf kunnen we echter niet zien of deze loopt of niet. We hebben een extra variabele voor controle nodig.
Hier een voorbeeld:
Klik!

Je ziet dat er nu na te klikken maximaal maar één timer gestart kan worden. Klikken verlengt alleen de tijd voor het dialoogvenster getoond wordt.
Als we een recursiefunctie willen die zichzelf langzaam herhaalt in plaats van oneindig snel, is het mogelijk om daarvoor te zorgen met de setTimeout()-functie. We kunnen op deze manier bijvoorbeeld een klok maken.
Hier een eenvoudig voorbeeld met een aftellende tijd in de statusbalk:
Tegenwoordig bestaat er ook nog de functie setInterval(), die zichzelf automatisch herhaalt en de bijbehorende functie clearInterval() om hem te stoppen. Bij deze methode gebruiken we dus geen recursie. Gebruik je wel recursie met een setInterval()-opdracht, dan neemt het aantal timers constant toe en ontstaat er uit eindelijk een "stack-overflow error", omdat er niet genoeg geheugen beschikbaar is voor al die timers.
Hier weer een voorbeeld van een aftellende tijd in de statusbalk, maar dan met de interval-functie in plaats van de timout-functie, zonder recursie:
Met deze functies kun je ook layers laten bewegen, zodat je een animatieachtig beeld krijgt. Alleen is het belangrijk te weten dat, wanneer we de positie van een layer opvragen, Internet Explorer de positiewaarden als een string met "px" erachter teruggeeft. Dat moeten we er dan dus uithalen. Hier is een voorbeeld van een bewegende layer, met een beweging en snelheid die eenvoudig in te stellen zijn:

Soms is het handig als we JavaScript opdrachten uit een string zouden kunnen laten interpreteren. Normaal gesproken wordt wat we in stringvorm schrijven niet herkend als JavaScript. Maar het is mogelijk een string uit te voeren als JavaScript-opdracht met de functie eval().
Voorbeeld:
Het is hiermee ook een manier om getallen in een string te herkennen als numberwaarde: "1" + 1 geeft 11, maar eval("1") + 1 geeft 2.

Wanneer we willen rekenen met getallen uit strings kunnen we soms teken problemen aanlopen. We kunnen het probleem hebben dat er tekst achter een getal in een string voorkomt die we weg willen hebben om met het getal foutloos een berekening te kunnen maken. Ook kunnen we situaties hebben waarin we de decimalen van een getal willen verwijderen.
Het is in JavaScript dan mogelijk parseFloat() en parseInt() te gebruiken.
Met de functie parseFloat() krijgen we een getal zonder tekst terug, van het number-datatype, als we een string meegeven waar voorin een getal staat en achterin tekst. Als we parsFloat("100 meter") gebruiken krijgen we dus de numberwaarde 100 terug. Als we achter de eerst voorkomende letter in een string weer getallen hebben staan zullen deze als tekst worden gezien en daarom ook worden verwijderd door parseFloat(). Bijvoorbeeld parseFloat("2.5a5") geeft dus geen 2.55, maar 2.5.
De functie parseInt() werkt zoals parseFloat(), maar haalt naast de tekst ook de cijfers achter de punt weg van een getal. Als we dus parseInt(2.5) doen levert dat 2 op. En parseInt("2.5a5") geeft ook 2.
Hier voorbeeld met parseFloat():
Om parseFloat(a) + parseFloat(b) staan trouwens haakjes om te zorgen dat deze twee numbers niet net als de rest van de string aan elkaar worden gekoppeld, maar dat ze bij elkaar worden opgeteld, en omdat deze optelling standaard geen voorrang heeft boven de deling door duizend. De voorrangsregels heb ik reeds duidelijk gemaakt in het hoofdstuk Operators.
Om nog een ander goed voorbeeld te geven van een situatie waarin we goed parseFloat() of parseInt() kunnen gebruiken, wil ik nog even verwijzen naar het layervoorbeeld wat ik zojuist gegeven heb in de uitleg over de timerfuncties. Daarin had ik in plaats van dit:

if (layer.style.left.indexOf("px") != -1)
{
    startleft = 1 * layer.style.left.substring(0, layer.style.left.charAt("px"));
}
else
{
    startleft = 1 * layer.style.left;
}

ook net zo goed dit kunnen doen:

startleft = parseFloat(layer.style.left);

Het is veel korter, en minstens even browseronafhankelijk.

Wanneer we vanuit een webpagina gegevens versturen via de URL, ondersteunen browsers het niet om alle tekens die er bestaan zomaar te versturen. Dit geld het meest voor oudere browsers, maar ook wel voor nieuwere.
Verzending van gegevens via de URL gebeurt meestal achter een vraagteken (?), wat de querystring wordt genoemd. In het hoofdstuk browserobjecten heb ik al verteld dat je de querysting kunt lezen met location.search.
Bij de verzending van een formulier worden vreemde tekens automatisch gecodeerd, en op de webserver weer gedecodeerd. Maar wanneer we rechtstreeks vanuit JavaScript gegevens via de URL sturen (gewoon via het location-object), worden ze niet gecodeerd en kunnen er fouten optreden vanwege deze tekens.
Om het probleem van de vreemde tekens op te lossen, bestaat er een functie die de tekens codeert, namelijk escape(). Zo wordt bijvoorbeeld een spatie " " omgezet naar "%20" door deze functie. En een regeleinde "\n" wordt omgezet in "%0A". Deze getallen achter het procentteken zijn de ACII-waarden van de tekens, de hexadecimale bytewaarden. Alle gewone letters uit een een string worden echter niet gecodeerd. Ook getallen niet. Bijvoorbeeld de tekens a b 1 2 blijven dus a b 1 2. En de leestekens _ . / @ + - * ook niet. Tekens met een streepje of puntjes er op, zoals é ë í ï ú ü á ä ó ö ý ÿ, worden wel gecodeerd. De tekens " ' , \ ! # $ % ^ & | ( ) { } [ ] worden ook gecodeerd. En ten slotte alle andere, nog vreemdere tekens worden zeker gecodeerd.
Voor het decoderen van gegevens kunnen we de functie unescape() gebruiken. Alle gecodeerde gegevens worden gedecodeerd door deze functie, maar alle niet gecodeerde gegevens worden rechtstreeks teruggegeven.
Hier een voorbeeld van het gebruik van beide functies:

JavaScript wordt vaak gebruikt voor het maken van zogenaamde rollover-images, image-elementen waarin we verwisselende afbeeldingen tonen, als reactie op muisevents, meestal mouseover- en mouseout-events. Wijziging van de afbeelding kan via de src-eigenschap. Hier volgt een voorbeeld van zo'n image-element, met verzonnen namen:
Probeer het maar eens uit met echte afbeeldingen, verwissel de hier gebruikte namen door echte locaties. Wanneer de muis over de afbeelding wordt geplaatst, wordt er een andere afbeelding getoond. Wanneer de muis weer van de afbeelding wordt afgehaald, wordt de oorspronkelijke afbeelding weer getoond. We zien dat dit werkt. Maar wanneer we dit echt vanaf het internet gaan gebruiken, zien we dat het allemaal erg traag reageert omdat de afbeeldingen die we tonen steeds opnieuw gedownload en geladen worden.
Het is mogelijk om hier wat aan te doen, door een object te maken van de constructor Image(). In zo'n object kun je bij het laden van de pagina een afbeelding opslaan, om deze later te tonen in een image-element. De afbeelding hoeft dan niet meer steeds opnieuw te worden geladen bij elke mouseover-mouseout-beweging. Even als een image-element heeft een Image-object een src-eigenschap waaraan we de afbeeldinglocatie toekennen. En zo kunnen met width en height de breedte en hoogte van de geladen afbeelding.
Het van te voren laden van een afbeelding met een Image-object, waardoor het laden later niet steeds opnieuw hoeft te gebeuren, wordt preloaden genoemd.
Hier volgt een voorbeeld van een rollover-image met preload, met het gebruik van Image() dus:
Gebruik hier ook eens bestaande afbeeldingen, en vergelijk het met het vorige voorbeeld. Probeer het uit op het internet. Als je browser preload ondersteund zul je zien dat op deze manier de afbeeldingen meteen te zien zullen zijn en niet vertraagd.

In JavaScript is het mogelijk om de tijd te weergeven. Dit kan met de constructor Date(). Deze constructor levert veel methoden aan een instantie ervan, maar geen eigenschappen. Date-objecten kunnen voor verschillende dingen handig zijn. Je kunt, zoals in het volgende hoofdstuk zal blijken er cookies mee instellen. Je kunt er de datum mee weergeven. Je kunt er de tijd mee tonen. En je kunt er zelfs ook nog klokjes mee maken op een pagina. Hiervoor is het echter belangrijk te weten hoe een Date-object in elkaar zit.
Het instantiëren kan met gewoon new Date(), wanneer je een Date-object met de huidige datum en tijd wilt maken. Wil je een andere datum of tijd instellen dan kun je dat in parameters meegeven aan de constructor. En dat kan op twee manieren: als één parameter van het datatype string of als losse parameters van het datatype number.
Als je een string invult kun je de datum ook volluit schrijven in het Engels. Je kunt bijvoorbeeld 30 augustus 2004 aanduiden als new Date("08/30/2004") of new Date("08-30-2004"), maar ook als new Date("August 30, 2004"), new Date("August 30 2004") of new Date("30 August 2004"). We kunnen daar ook nog de tijd bijzetten, dus bijvoorbeeld new Date("30 August 2004, 17:30:00") of new Date("08/30/2004 17:30") enzovoorts. Wat je van de tijd niet invult wordt automatisch op 0 gezet.
Als je numberparameters invult is de volgorde als volgt: new Date(jaar, maand, datum, uur, minuten, seconden). Met de datum 30 augustus 2004 en de tijd 17:30 vullen we new Date(2004, 7, 30, 17, 30, 0) in. Geef je alleen de datumparameters op, dan wordt de tijd automatisch 00:00:00. Zo wordt de datum standaard 1. Geven we alleen 0 op als eerste parameter, en geen andere parameters, dan wordt de standaardtijd ingesteld, namelijk 1 januari 1970 1:00:00. Terwijl we met helemaal niets in te vullen de datum en tijd van het huidige moment krijgen.
Belangrijk om te weten is dat de telling van de maanden van 0 t/m 11 loopt en niet van 1 t/m 12. Vandaar dat we voor augustus 7 invullen en geen 8.
Als je het Date-object gedefinieerd hebt kun je het daarna nog wijzigen via een parameter in de volgende methoden:
 - setFullYear() stelt het jaar in.
 - setYear() stelt het jaar in.
 - setMonth() stelt de maand in.
 - setDate() stelt de datum in.
 - setHours() stelt het uur in.
 - setMinutes() stelt de minuten in.
 - setSeconds() stelt de seconden in.
 - setMilliseconds() stelt de milliseconden in.
 - setTime() stelt het aantal milliseconden in sinds 1 jan 1970 1:00:00.

De waarden van je Date-object kun je opvragen met de volgende methoden:
 - getFullYear() geeft het jaar volledig.
 - getYear() geeft het jaar alleen volledig in Internet Explorer.
 - getMonth() geeft de maand.
 - getDate() geeft de datum.
 - getDay() geeft de dag van de week.
 - getHours() geeft het uur.
 - getMinutes() geeft de minuten.
 - getSeconds() geeft de seconden.
 - getMilliseconds() geeft de milliseconden.
 - getTime() geeft het aantal milliseconden sinds 1 jan 1970 1:00:00.

Het is trouwens af te raden de getYear()-methode te gebruiken als we het jaar rechtstreeks willen tonen, omdat deze methode in andere browsers dan in Internet Explorer het jaar afgekort weergeeft en omdat er vanaf 2000 dan ook nog een 1 voor wordt gezet. Dus bijvoorbeeld 2004 wordt met getYear() weergeven als 104 in andere browsers dan Internet Explorer. Gebruik daarom getFullYear().
Ten slotte zijn er nog een aantal methoden die een groot deel van een Date-object teruggeven als string:
 - toString() geeft de datum en tijd in het Engels.
 - toUTCString() geeft van de Greenwich Mean Time de datum en tijd.
 - toGMTString() geeft van de Greenwich Mean Time de datum en tijd.
 - toLocaleString() geeft de datum en tijd in de taal van de bezoeker.
 - toDateString() geeft de datum in het Engels.
 - toTimeString() geeft de tijd in het Engels.
 - toLocaleDateString() geeft de datum in de taal van de bezoeker.
 - toLocaleTimeString() geeft de tijd in de taal van de bezoeker.

Als je het Date-object zelf toont wordt automatisch de toString()-methode ervan aangeroepen.
Hier volgt een voorbeeld met de huidige tijd in verschillede strings getoond:
In combinatie met de methode setTimeout() of de methode setInterval() is het in JavaScript heel eenvoudig om lopende klokjes te maken met de tijd. We moeten dan steeds opnieuw de constructor Date() aan roepen. Daarom is het dan niet zinvol onze Date-instantie ook helemaal toe te kennen aan een variabele. We roepen gewoon direct de toLocaleTimeString()-methode aan en tonen hiermee steeds de tijd.
Hier een klokje in de statusbalk:
Met de methoden uit het Date-objecttype kunnen we de tijd alleen in cijfers uitgedrukt zien, maar wanneer je deze cijfers gebruikt om stringwaarden uit een zelfgemaakt array te kiezen, kun je de tijd ook in woorden weergeven. Dat gaat bijvoorbeeld zo:

Met operators is het in JavaScript o.a. mogelijk om op te tellen, af te trekken, te vermenigvuldigen en te delen. Maar met operators kun je niet zomaar machten berekenen, wortels trekken, logaritmen berekenen, of constanten opvragen als het getal Pi, enzovoorts.
In JavaScript is daarvoor een speciaal object dat Math heet. Het bevat een aantal handige rekenmethoden en het bevat eigenschappen met bepaalde constante waarden.
Hier volgen de methoden van het Math-object met een beschrijving:

Math.random() - een randomgetal tussen 0 en 1.

Math.abs(waarde) - de absolute waarde van waarde.

Math.round(waarde) - waade afronden naar dichtstbijzijnde hele getal.

Math.floor(waarde) - waarde omlaag afronden naar heel getal.

Math.ceil(waarde) - waarde omhoog afronden naar heel getal.

Math.max(waarde1, waarde2) - het grootste getal van waarde1 en waarde2.

Math.min(waarde1, waarde2) - het kleinste getal van waarde1 en waarde2.

Math.pow(waarde1, waarde2) - waarde1 tot de macht waarde2.

Math.sqrt(waarde) - de (kwadratische) wortel van waarde.

Math.log(waarde) - het natuurlijke logaritme van waarde.

Math.exp(waarde) - de exponent van waarde.

Math.sin(waarde in radialen) - de sinus van waarde.

Math.cos(waarde in radialen) - de cosinus van waarde.

Math.tan(waarde in radialen) - de tangens van waarde.

Math.asin(waarde) - de boogsinus van waarde in radialen.

Math.acos(waarde) - de boogcosinus van waarde in radialen.

Math.atan(waarde) - de boogtangens van waarde in radialen.

Math.atan2(waarde1, waarde2) - de boogtangens van waarde1 / waarde2 in radialen.


En hier volgen de eigenschappen met een beschrijving:

Math.PI - het getal Pi (verhouding tussen diameter en omtrek in een cirkel).

Math.E - het getal e van Euler.

Math.LOG2E - Het 2e logaritme van het getal e.

Math.LOG10E - Het 10e logaritme van het getal e.

Math.LN2 - het natuurlijke logaritme van 2.

Math.LN10 - het natuurlijke logaritme van 10.

Math.SQRT1_2 - De (kwadratische) wortel van 1/2.

Math.SQRT2 - De (kwadratische) wortel van 2.


Met al deze methoden en eigenschappen behoort het Math-object tot de meest handige en multifunctionele dingen die er zijn in JavaScript.
Zo kun je bijvoorbeeld de randomgetalmethode heel handig gebruiken in combinatie met een afrondmethode om zo iets willekeurigs te doen met JavaScript. Je kunt zo bijvoorbeeld een random gekozen plaatje tonen op je website, als je een aantal URL's in een array zet. Als je een groter randomgetal wilt dan tussen 0 en 1. Dan kun je dat simpelweg doen door een bepaald getal ermee te vermenigvuldigen. Zo levert 5 * Math.random() een decimaal getal op tussen 0 en 5. Afgerond met Math.floor() levert dit een heel getal op van 0 t/m 4.
Hier volgt een voorbeeld van het gebruik van Math.random() met afbeeldingen:
Verwissel de hier verzonnen bestandsnamen door bestaande bestandsnamen.
En met de trigonometrische methoden kun je hele bijzondere grafische effecten maken. Hier volgt een grappig voorbeeld van een layer die golfbeweging maakt door een sinusberekening:

Terug naar Inhoudsopgave


Cookies

Het gebruik van cookies op een site is een van de dingen die vrij bekend en berucht zijn van JavaScript. Een cookie is soort een bestandje dat met JavaScript op een webpagina toegankelijk is om er gegevens in op te slaan en er uit te halen.
Cookies kunnen bijvoorbeeld handig zijn als je een systeem wilt maken op een site waarbij de bezoekers dingen mogen instellen op de site en als je die instellingen dan wilt behouden. Je zou de gebruikers bijvoorbeeld de indeling van de menu's op de site kunnen laten instellen. Of als er een inlogsysteem op een site is, dan is het mogelijk de inlognaam van de bezoeker te onthouden in een cookie op zijn of haar pc, zodat hij of zij de inlognaam bij het volgende bezoek aan de site niet helemaal opnieuw hoeft in te vullen, maar dat deze er dan al staat. En je kunt de bezoeker bij het eerste bezoek aan een site zijn of haar naam laten invullen en vervolgens de volgende keer de bezoeker verwelkomen met die naam, als je die opslaat in een cookie.
Maar aan cookies zit ook een nadeel: ze kunnen schadelijk zijn voor de privacy van de bezoeker. Als een gebruiker zijn bijvoorbeeld zijn of haar rekeningnummer een keer invult op een site, dan kan dat dus worden onthouden in een cookie en dan blijft zo'n site daardoor toegang krijgen tot dat rekeningnummer en zou daar dan vervolgens misbruik van kunnen maken. Als dat gebeurt kun je dus het beste die cookie zo snel mogelijk van je pc verwijderen. En verder kun je ook de controle op cookies in je browser zo hoog instellen als je maar wilt. Maar alle cookies volledig blokkeren is dus ook niet slim: je kunt dan geen sites voor e-mail en inlogsystemen probleemloos meer gebruiken die sterk afhankelijk zijn van het gebruik van cookies.

Een cookie maak je, wijzig je en lees je met de eigenschap document.cookie. Gegevens opslaan gebeurt via toekenning in een string, op de manier "naam=waarde", gescheiden door puntkomma's ";". Als je dus een postcode 1234AB hebt een een plaatsnaam Amsterdam, dan zou je dit in een cookie op kunnen slaan met:
document.cookie = "postcode=1234B; plaatsnaam=Amsterdam";
Meestal zul je echter met een aantal variabelen werken en dan kun je natuurlijk ook dit doen:
document.cookie = "postcode=" + postcode + "; plaatsnaam=" + plaatsnaam;
waarbij postcode dan "1234AB" als waarde kan hebben en plaatsnaam dan "Amsterdam" als waarde kan hebben.
Deze cookie kan dan vervolgens ook door andere pagina's op dezelfde website worden opgevraagd met document.cookie. De waarde "postcode=1234B;plaatsnaam=Amsterdam" zal dan worden teruggegeven. Met substring()- en indexOf()-opdrachten kunnen de gegevens vervolgens worden opgezocht uit deze string en verder worden gebruikt.

Standaard gaat een cookie echter meteen weer verloren wanneer de browser wordt afgesloten. Maar het is mogelijk om dit anders op te geven, namelijk met de optie "expires". Hieraan geef je de tijd mee wanneer de cookie verloopt. Deze tijd moet in het UTC-formaat zijn van het Date-objecttype. Je moet dus de methode toUTCString() of de methode toGMTString() uit een Date-object gebruiken. De cookie blijft dan beschikbaar voor de site tot deze verloopdatum.
Hier heb ik een voorbeeld van een script dat in een cookie voor ongeveer een jaar lang de naam van de pagina bezoeker kan onthouden, en ook verlengt het script deze periode steeds weer opnieuw tot ongeveer een jaar bij elk volgend bezoek aan de pagina:
Als er op een website een cookie wordt aangemaakt, is deze niet beschikbaar voor andere sites, maar wel voor andere pagina's binnen dezelfde site. Standaard geld echter de regel dat een cookie alleen beschikbaar is voor pagina's binnen dezelfde directory van de website en voor pagina's van subdirectories en niet beschikbaar is voor pagina's van hogere directories en parallelle directories.
Dus een cookie van bijv. http://www.jskoekenbakkers.com/dir1/dir2/eerstepagina.html is ook beschikbaar op http://www.jskoekenbakkers.com/dir1/dir2/tweedepagina.html en op http://www.jskoekenbakkers.com/dir1/dir2/dir3/pagina.html, maar niet op http://www.jskoekenbakkers.com/dir1/pagina.html en http://www.jskoekenbakkers.com/dir1/paralleledir/pagina.html.
Willen we dit anders instellen dan kunnen we de optie "path" gebruiken om aan te geven in welke directory van de website de cookie gezien mag worden. Om een cookie in te stellen voor de hele website kun je "path=/" gebruiken ("/" verwijst naar hoofddirectory en bijv. "/dir1/" verwijst naar een directory die dir1 heet).
En verder is het niet mogelijk om een heel andere website in te stellen, maar wat wel mag is een ander subdomein instellen met "domain". Als een pagina zich bevind op www.jskoekenbakkers.com dan mag ook "domain=lekkerstekoekjes.jskoekenbakkers.com" worden ingesteld. Maar "domain=www.jsbroodbakkers.com" zal niet werken.

En ten slotte is het nog mogelijk om een cookie alleen bij een beveiligde verbinding (HTTPS-protocol) beschikbaar te stellen, namelijk met "secure". Aan "secure" wordt geen waarde gegeven, het wordt alleen genoemd.

Een toekenning aan een cookie kan er dus bijvoorbeeld zo uitzien:
document.cookie = "naam=Jan; expires=Sun, 3 Oct 2004 0:0:0 UTC; path=/; domain=www.jskoekenbakkers.com; secure";

Terug naar Inhoudsopgave


ActiveX

Het JavaScript van Microsoft verschilt, zoals ik al eerder verteld heb, in een aantal opzichten van het JavaScript dat Netscape ontwikkeld heeft. Eigenlijk heet het JavaScript van Microsoft ook geen JavaScript, maar Microsoft JScript. Een van de grootste verschillen tussen echt JavaScript en Microsoft JScript is uitbreiding voor ActiveX-besturingselementen die in MS JScript zit. Deze ActiveX-ondersteuning maakt het mogelijk vanuit JavaScript te communiceren met het systeem en programma's die zich buiten webpagina en buiten de browser bevinden.
Dit is erg handig, maar ook erg onveilig. Door ActiveX-ondersteuning wordt het dus mogelijk voor allerlei websites om toegang te krijgen tot de pc van de paginabezoeker. Dit is leuk als je kijkt naar wat er dan mogelijk is met bijvoorbeeld het Dynamischer maken van een website. Je kunt bijvoorbeeld bestanden kopiëren naar de pc van de bezoeker en deze dan automatisch openen en tonen. Maar het wordt zo helaas ook mogelijk allerlei kwaadaardige dingen te doen op de pc van bezoeker, waar de bezoeker niet blij mee is, bijvoorbeeld automatisch virussen laten downloaden en ze hun vernietigende werking laten doen. Gelukkig moet de bezoeker in de Internet Explorer een ActiveX-onderdeel eerst accepteren voor het kan worden uitgevoerd. Maar hierin hebben in het verleden wel een aantal lekken gezeten waardoor op een bepaalde manier ActiveX-scripts toch gewoon uitgevoerd konden worden en konden binnendringen op een pc. Maar dit is steeds beter geworden, Internet Explorer is steeds meer bugvrij.
Alle andere browser dan Internet Explorer hebben dit ActiveX-script niet en daarom moet je je dus realiseren dat een pagina met ActiveX-scripts erg browserafhankelijk is.
In dit hoofdstuk zal ik daarom slechts een paar algemene dingen over ActiveX-scripting noemen. Als je er echt veel van wilt weten raad ik het aan een aparte tutorial over dit onderwerp te gaan doen.

Een ActiveX-besturingselement gebruik je door een speciaal soort object te maken, een ActiveX-object. Dit kan met de Constructor ActiveXObject(type). Hierbij bedoel ik met type een parameter waarmee aangeeft welk type ActiveX-besturingselement je wilt gebruiken.

Een belangrijk voorbeeld van een type ActiveX-object is het FileSystemObject. Hiermee krijg je toegang tot het bestandsysteem van Windows. Je kunt met dit object bestanden en directories maken, kopiëren, verplaatsen, van naam wijzigen en verwijderen. Maar daarnaast kun je ook bestanden lezen en in bestanden schrijven.
Een FileSystemObject is dus zo'n beetje het meest handige, maar ook het meest onveilige ActiveX-object dat er is.
Om dit object te maken moeten we de string "Scripting.FileSystemObject" meegeven aan de constructor ActiveXObject().
Hier volgen een paar methoden van het FileSystemObject met uitleg (waarbij ik met FSO het FileSystemObject bedoel, dat je zelf gedefinieerd moet hebben):

FSO.CreateTextFile(bestand) - maakt een bestand aan met de naam/locatie bestand en geeft een tekststroom-object van het bestand als waarde terug.
FSO.OpenTextFile(bestand, stroommodus)* - opent een bestand met de naam/locatie bestand en geeft een tekststroom-object van het bestand als waarde terug.
FSO.GetFile(bestand) - geeft een bestand met de naam/locatie bestand als waarde terug.
FSO.CopyFile(bestand, doel) - kopieert het bestand bestand naar doel.
FSO.MoveFile(bestand, doel) - kopieert het bestand bestand naar doel.
FSO.DeleteFile(bestand) - verwijdert het bestand bestand.
FSO.FileExist(bestand) - geeft met een booleanwaarde aan of het bestand bestand bestaat.
FSO.GetFolder(directory) - geeft een directory met de naam/locatie directory als waarde terug.
FSO.CopyFolder(directory, doel) - kopieert de directory directory naar doel.
FSO.MoveFolder(directory, doel) - kopieert de directory directory naar doel.
FSO.DeleteFolder(directory) - verwijdert de directory directory.
FSO.FolderExist(directory) - geeft met een booleanwaarde aan of de directory directory bestaat.
FSO.GetFile(station) - geeft een station met de naam station als waarde terug.
FSO.DriveExist(station) - geeft met een booleanwaarde aan of het station station bestaat.
* de parameter stroommodus is een numberwaarde aangeeft of het bestand geopend moet worden om te lezen (1), of het bestand geopend moet worden om te herschrijven (2), of dat het bestand geopend moet worden om er gegevens bij te schrijven (8).

Verder hebben de objecten van de Get-methoden van het FileSystemObject, de bestand-objecten en directory-objecten, ook nog een aantal methoden (met file bedoel ik hier dus dat object):

file.OpenAsTextStream(stroommodus) - opent het bestand / de directory en geeft een tekststroom-object ervan als waarde terug.
file.Copy(doel) - kopieert het bestand / de directory naar doel.
file.Move() - verplaatst het bestand / de directory naar doel.
file.Delete() - verwijdert het bestand / de directory.
file.Exist() - geeft met een booleanwaarde aan of het bestand / de directory bestaat.

Maar een directory-object heeft alleen geen OpenAsTextStream()-methode.
En ten slotte heeft tekststroom uit de Open-methoden ook nog methoden, namelijk (stroom is hier dat object):

file.Write(tekst) - schrijft de string tekst.
file.WriteLine(tekst) - schrijft de string tekst en eindigt met een niewe regel ("\r\n").
file.Close() - sluit de stroom af.

Naast dit alles is er nog iets speciaals aan ActiveX-JScript: het kan ook buiten de InternetExplorer worden uitgevoerd, met andere programma's. Het belangrijkste programma waar we dan mee te maken hebben is het Windows Script Host. Dit programma is standaard geïnstalleerd in Windows en bestaat in twee vormen: cscript.exe en wscript.exe. cscript.exe is de consolevariant (commandline). wscript.exe is de windowsvariant. Het Windows Script Host kan VBScript en JScript van het ActiveX-type uitvoeren. VBScript sla je op met de extensie .vbs en JScript sla je gewoon op met de extensie .js. Standaard zijn .vbs en .js via dubbelklik geassocieerd met wscript.exe en zijn zo dus eenvoudig uitvoerbaar. Deze scripts kunnen erg handig zijn om bijvoorbeeld een ingewikkelde kopieeropdracht van bestanden via dubbelklik uit te voeren en om deze opdracht later ook weer snel opnieuw te kunnen uitvoeren.

Hier volgt een voorbeeld van een script die een bestand maakt en er de output van een for-lus inzet:
Sla het op als "lus.js" en voer het uit met het Windows Script Host.

En ten slotte kan dit JavaScript soms ook nog server-side gebruikt worden. Dit is onder andere het geval in ASP-pagina's. ASP is zelf eigenlijk maar een heel kleine taal, die als "container"-taal dient voor andere talen. Binnen ASP-tags gebruik je bijvoorbeeld C#, VB, VBScript of JScript om dingen uit te voeren op de server. Dit kan bijvoorbeeld het verwerken of opslaan van verzonden gegevens zijn, of het lezen van bestanden of databases. Een nieuwere vorm van ASP is ASP.NET, die onderdeel is van het .NET Framework. Het .NET Framework is een grote ontwikkelomgeving voor allerlei programmeertalen.

Terug naar Inhoudsopgave


VBScript

VBScript (Visual Basic Script) is een taal die wat betreft de inhoud sterk lijkt op JScript, maar dan met een hele andere syntaxis, die vrijwel gelijk is aan die van Visual Basic (VB). Het nadeel van VBScript is echter dat deze, wat browsers betreft, uitsluitend ondersteund wordt door Internet Explorer. JavaScript is juist standaard in allerlei browsers. Maar als je kijkt naar de ActiveX-ondersteuning van VBScript, dan is VBScript beter. VBScript heeft namelijk nog wat meer ActiveX-mogelijkheden dan JScript.

De syntaxis van VBScript verschilt onder andere van JavaScript als je kijkt naar de markeringen voor aanduiding of iets begint of eindigt. Eigenlijk kun je twee groepen programmeer- en scripttalen onderscheiden van dit betreft. Talen zoals Pascal, Delphi, Visual Basic en VBScript markeren het begin en einde van functies, lussen en andere blokken met statements, met woorden. Maar talen zoals C, C++, Java en JavaScript markeren alles veel meer met haakjes en accolades.
En verder worden gewone functies in VB en VBScript ook geen functies genoemd, maar subroutines. Ze worden genoteerd met Sub en niet met function. Functies in VB en VBScript zijn vergelijkbaar met subroutines, maar ze kunnen een waarde teruggeven. Subroutines kunnen dat niet. Functies worden genoteerd met Function.
Een derde zeer belangrijk verschil is dat VBScript niet hoofdlettergevoelig is. JavaScript is dit wel. Zo mag bijvoorbeeld Function in VBScript ook best worden geschreven als FUNCTION, function of zelfs fUnCtIoN, enzovoorts.
Maar dat betekend ook dat als je eerst een subroutine definieert die a() heet en daarna een die A() heet, dat de tweede definitie gewoon zal gelden als een vervanging van de eerste.
Overigens eindigen opdrachten in VBScript ook niet met puntkomma's.

Hier volgt een voorbeeldscript:
AciveX-gebruik in VBScript wordt anders gedefinieerd dan in JavaScript. Het wordt niet gedaan met de constructor ActiveXObject(), maar met een functie die CreateObject() heet, met een gewone aanroep, geen instantiering via new.
Voorbeeld (voor het Windows Script Host):
Let vooral ook op het verschil in notatie van de for-lus.

Op één webpagina in Internet Explorer kunnen zowel JavaScripts als VBScripts worden uitgevoerd. Het is hierbij ook nog eens zo dat er sterke communicatie mogelijk is tussen deze scripts. In JScript mogen subroutines en functies uit VBScript worden aangeroepen, alsof het gewoon functies in JScript zelf zijn. En andersom mogen in JScript gedefinieerde functies ook worden aangeroepen vanuit VBScript, alsof het subroutines of functies uit VBScript zijn.

VBScript is dus een soort JavaScript-achtige scriptvorm van Visual Basic. Er is ook nog een andere kleine vorm van Visual Basic. Namelijk een taal die ingevoegd wordt als een zogeheten macro in MS Office programma's, zoals Word en Excel. Die VB-vorm wordt VBA, Visual Basic for Applications, genoemd.
Echt Visual Basic is echter een volledige programmeertaal waarmee programma's van EXE-formaat worden gemaakt. Even als bijvoorbeeld C++ en Java gebruikt deze taal ook klassen en objecten. Het is dus een objectgeoriënteerde taal. Dit echte Visual Basic zit ook in het .NET Framework en wordt vaak gebruikt in ASP-pagina's.

Terug naar Inhoudsopgave


Java

JavaScript lijkt, zoals de naam al zegt, sterk Java, een programmeertaal die door Sun Microsystems is ontwikkeld. In feite stamt JavaScript van Java af. Heel veel dingen in JavaScript zijn bijna letterlijk uit Java afkomstig, bijvoorbeeld indexOf() en substring() in strings, toString(), Date(), Math, en nog veel meer. En ook de hele syntaxis komt in veel opzichten overeen. Daarom is het de moeite waard in dit hoofdstuk een kleine basisuitleg te geven over deze goede programmeertaal en over de verbanden tussen Java en JavaScript.

Java is echter veel meer dan JavaScript een echte een objectgeoriënteerde programmeertaal. En bovendien is het gebruik van een Java-programma ook heel anders dan een JavaScript-script. Java kan draaien als een zelfstandige toepassing in een eigen venster en/of in commandline-venster. En er is ook een speciaal type Java-programma, dat als invoegtoepassing kan draaien in een pagina (vergelijkbaar met Flash). Zo'n invoegtoepassing wordt een applet genoemd. Zo'n applet wordt, en in tegenstelling tot JavaScript, niet in de broncode van de pagina waar die in draait geschreven, maar in een apart bestand.
Bovendien is een Java-programma niet uitvoerbaar als sourcecode, maar alleen in gecompileerde vorm, als een zogeheten "ByteCode". Sourcecodes hebben de extensie .java. ByteCodes hebben de extensie .class en ze worden ook wel classfiles genoemd. Het compileerprogramma voor Java heet javac. Het zit in de JDK van Sun Microsystems.
Classfiles kunnen ook in een speciaal archief gezet worden, een jarfile, dat de extensie .jar heeft. JAR is een afkorting voor Java Archive. Een archief is een gecomprimeerd bestand (voorbeelden: ZIP, JAR, TAR, RAR). Uit een jarfile kunnen de classfiles automatisch worden aangeroepen en worden gestart. Jarfiles zijn oa. handig voor applets, om het downloaden ervan te versnellen.
Na compilatie is een Java-programma nog steeds niet zomaar uit te voeren. Er is een speciaal interpreteerprogramma nodig om iets met Java te kunnen: een Virtual Machine (VM). Een Java-ByteCode is namelijk geen pure machinetaal. Het bestaat dus niet uit rechtstreekse processorinstructies, maar uit een eigen soort instructies, die alleen door een VM begrepen worden.
Het voordeel van deze wijze van uitvoering is dat een Java-programma daardoor platform-onafhankelijk is aangezien machinecode per computer en vooral ook per besturingssysteem kunnen verschillen.
Er is op deze manier maar een ding wat er in eigen versies moet zijn voor verschillende systemen. Dat is de virtual machine.
Een ander voordeel is dat Java zo een heel veilige taal is, want de Virtual Machine kan uiteindelijk van elke opdracht in het programma bepalen of deze uitgevoerd mag worden. Applets hebben geen toegang tot de bestanden op de harddisk van een sitebezoeker. Alleen echte toepassingen in Java, die buiten de browser draaien, hebben dit lees- en schrijfrecht op de harddisk.
En alle voorgeprogrammeerde onderdelen die er in Java zijn, de zogeheten API, die worden in tegenstelling tot bijvoorbeeld C en C++, bij de compilatie niet met het programma versmolten, maar er wordt slechts naar verwezen in een ByteCode. Het is de Virtual Machine die dan de API laadt waarnaar wordt verwezen. Hierdoor is de bestandgrootte van een Java-programma heel klein, wat vooral bij applets een voordeel is, voor een snelle downloading er van.

Het feit dat Java een objectgeoriënteerde taal (OO-taal) is betekent kort gezegd eigenlijk het volgende:
Daarvan komt alleen instantiëring voor in een objectgebaseerde taal, zoals JavaScript. In JavaScript komen klassen, overerving en afscherming niet voor.

Een ander zeer belangrijk verschil van Java vergeleken met JavaScript is de veel sterkere scheiding tussen de verschillende datatypen/objecttypen binnen Java. In Java moet er van elke variabele aangegeven worden tot welk datatype de waarde ervan hoort. Er is geen statement var om een variabele te declareren en er is geen statement function om functies te declareren. In de plaats hiervan wordt het type genoemd van de waarde, bij functies het type van de teruggegeven waarde door het return-statement.
Zo wordt een een stringvariable niet gedefinieerd met bijvoorbeeld variabele1 = "Hallo!"; of met var variabele1 = "Hallo!";, maar met bijvoorbeeld String variabele1 = "Hallo!";. En een object van een type Date wordt bijvoorbeeld gedefinieerd met Date dateobject1 = new Date();. Eerst declareren en later pas een waarde toekennen mag ook. Dus bijvoorbeeld eerst Date dateobject1 en later dateobject1 = new Date();.
Een functie die bijvoorbeeld methode1 heet en een string als waarde teruggeeft kan als volgt worden gedefinieerd:

public String methode1()
{
    // Hier kunnen allerlei opdrachten staan.
    return "Een string";
}

Als de functie geen waarde teruggeeft (void-type), ziet deze er bijvoorbeeld zo uit:

public void methode1()
{
    // Hier kunnen allerlei opdrachten staan.
}


Ook een groot verschil met JavaScript is dat binnen elk blok accolades de variabelen lokaal kunnen zijn, naast functies. In het volgende voorbeeld is variabele a niet zichtbaar in het gebied van variabele b:

{

    {

        String a = "Hallo!";

    }

    int b = 10;

}

in JavaScript worden objecttypen, zoals ik in het hoofdstuk Objecten uitgelegd heb, gedefinieerd met functies. Zulke functies worden ook wel constructors genoemd. Deze functies verschillen niet van andere functies in de definiëring, behalve het gebruik van het statement this, om variabelen en functies te plaatsen in een objecttype. Het grote verschil tussen normale uitvoering van functies en object-definiëring zit dus niet hierin. Iedere functie kan worden geïnstantieerd tot object. Het verschil zit dus slechts in de aanroep, in het gebruik van het statement new.
In Java werkt dit allemaal anders, het zit ingewikkelder in elkaar. Objecttypen worden gedefinieerd met klassen. Klassen zijn hoofdonderdelen van een programma, waarbinnen je alle variabelen en functies definieert. Na compilatie komt er voor elke klasse trouwens een eigen classfile.
In Java staan alle variabelen en functies in klassen en nooit daar buiten. Klassen kunnen ook binnen elkaar gezet worden, oftewel genest worden. De functies kunnen, in tegenstelling tot in JavaScript niet genest worden. En bovendien kunnen er geen opdrachten worden uitgevoerd buiten functies. Dus bijvoorbeeld controleopdrachten, lussen en aanroepen van gewone functies staan uitsluitend binnen de functies. En een Java-programma start daarom ook altijd al automatisch met de aanroep van bepaalde functies die je definieert, iets wat in JavaScript ongewoon is. Vanuit een automatisch gestarte functie kun je zelf dan andere functies aanroepen.
Alleen toekenningen van waarden aan variabelen en daarbij horende instantiëringen kunnen worden gedaan buiten functies.
Er is in een klasse ook een functie die bij instantiëring van de klasse wordt aangeroepen, namelijk de constructor. Een constructor is in Java, in tegenstelling tot in JavaScript, wél een speciaal soort functie. Hij heeft namelijk geen datatype, en wordt ook zonder datatype gedeclareerd (ook geen void).
Een klasse wordt gedefinieerd met het statement class en daarachter de naam die je er aan geeft. Hierachter komen vervolgens accolades { }, waartussen alle variabelen en functies gezet kunnen worden.
Hier volgt een voorbeeld van een klasse, die opgeslagen dient te worden als Klasse1.java:

Een klasse kan vanuit andere klassen worden geïnstantieerd tot object. Ook binnen zichzelf kan een klasse worden geïnstantieerd. Net als in JavaScript gaat instantiëring via het statement new.
Een variabele waaraan je een instantie toekent met echter ook altijd als declaratie de klassenaam hebben, aangezien de klasse dan het type is. De hierboven gegeven voorbeeld-klasse kan bijvoorbeeld worden geïnstantieerd met Klasse1 object1 = new Klasse1();. Vervolgens zou methode1() er uit aangeroepen kunnen worden met object1.methode1();.

Naast instantiering is er in Java nog een heel belangrijke manier waarop gegevens uit de een klasse voor andere klasse beschikbaar kunnen worden, namelijk overerving. Functies uit een klasse kunnen via overerving rechtstreeks beschikbaar voor andere klassen. Een klasse die Klasse1 zou overerven kan gewoon rechtstreeks de aanroep methode1(); doen. Overerving gebeurt achter de naam van de klasse die je definieert, met het statement extends en vervolgens de naam van de overgeërfde klasse. Een overgeërfde klasse wordt een superklasse genoemd. Een klasse die een andere klasse overerft is een subklasse.
Een voorbeeld van overerving:

class Klasse2 extends Klasse1
{

    public Klasse2()
    {
        // Roep methode1 van de superklasse aan:
        methode1();
    }

}


Functies en variabelen kunnen echter ook onbeschikbaar gemaakt worden voor andere klassen. Dit onderscheid wordt gemaakt met de statements public en private. Functies en variabelen die public gedeclareerd zijn, zijn aanroepbaar via overerving en in objecten. Maar als ze private zijn, zijn ze dat niet, ze zijn dan afgeschermd.
Ook hier is Klasse1 weer een goed voorbeeld: methode2() is private. Probeer je deze functie aan te roepen vanuit een andere klasse, dan zal de compiler een foutmelding geven. Naast public en private bestaat er ook nog een statement protected, waarmee andere klasse in slechts beperkte mate toegang tot zo'n functie of variabele krijgen.
Verder kan ook een hele klasse nog public worden gedeclareerd. Voor een public klasse geldt trouwens de regel dat deze in een javabestand moet staan dat een gelijke bestandsnaam heeft aan de naam van deze klasse. Voor niet-public klassen geld dit niet.
Er kan per javabestand dus maar een public-klasse zijn. Maar een Java-programma kan uit meerdere van deze bestanden bestaan, dus dat is geen probleem.

Een laatste belangrijk verschil met JavaScript is het feit dat er in Java meerdere gelijknamige functies kunnen zijn, als deze verschillende parameters hebben. Dit kenmerk van Java wordt polymorfisme genoemd. Hiermee is het mogelijk om op basis van verschillende parameters totaal verschillende dingen uit te voeren. Hier tegenover staat echter wel dat in Java uitsluitend die parameters meegegeven mogen worden aan de functie bij aanroep, en geen andere. Ook het aantal meegegeven parameters moet kloppen. In JavaScript is het zo dat een functie met bijvoorbeeld drie parameters ook kan worden aangeroepen met bijvoorbeeld twee of vier parameters.
In JavaScript moeten er dus waarde controlerende opdrachten worden uitgevoerd in één functie om op basis van andere parameters of een andere aantal parameters verschillende opdrachten uit te voeren, terwijl je in Java dus aparte functies maakt met dezelfde naam.

Zoals ik reeds verteld heb, zijn er functies waarmee een Java-programma start.
Als je een toepassing scrijft is dit de mainfunctie. Om precies te zijn, deze functie moet public static void main(String args[]) heten. Hier een voorbeeld van een programma dat Klasse1 instantieert en daarvan methode1 aanroept:
Om dit programma uit te compileren moet in de commandline de volgende opdracht worden uitgevoerd (als de JDK is geïnstalleerd natuurlijk):

javac Klasse1.java mainapp.java

Om de zo gecreëerde classfiles daarna uit te voeren, moet deze opdracht worden uitgevoerd:

java mainapp

Dit moet allemaal in dezelfde directory gebeuren en ook de twee sourcefiles moeten in dezelfde directory staan.
Je zult zien dat er twee keer de tekst "Hallo!" verschijnt in de commandline. De eerste is van de constructor, wanneer Klasse1 wordt geïnstantieerd. De constructor roept namelijk methode1() aan. De tweede tekst komt door het direct aanroepen van methode1().

Nu een vergelijkbaar voorbeeld via overerving (compileer en voer uit op dezelfde manier):
Je zult zien dat Klasse1 inderdaad overgeërfd is en dat de aanroep van methode1() uit Klasse1 weer de tekst "Hallo!" toont.
Overigens kan methode1() niet zonder instantiering van MainClass in een mainfunctie worden aangeroepen. Dat komt door de static declaratie.
Vanuit non-static functies mag methode1() wel direct worden aangeroepen, bijvoorbeeld uit een constructor.

Applets starten niet met een mainfunctie, maar met een functie die init() heet en daarna ook nog met een functie die start() heet. En verder is er ook nog een functie paint(java.awt.Graphics), die zelfs meerdere keren automatisch kan worden aangeroepen. de parameter van de klasse java.awt.Graphics is een object met allerlei grafische methoden.
Een klasse kan echter niet zomaar als applet worden uitgevoerd. Om een applet te maken gebruik je klasse java.applet.Applet voor overerving.
Een leeg applet kan er bijvoorbeeld zo uitzien:

public class EenApplet extends java.applet.Applet
{

    public void init()
    {

    }

    public void start()
    {

    }

    public void paint(java.awt.Graphics g)
    {

    }

}

Applets plaats je op webpagina's met <applet>-tags. Er zijn hierin een paar belangrijke attributen, namelijk code, codebase, archive, width en height.
Met code geef je aan welke klasse er moet worden aan geroepen. Dit moet een subklasse zijn van de Applet-klasse.
Met codebase geef je aan wat de basisdirectory is waarin gezocht moet worden naar klassen. Als dit attribuut niet gebruikt wordt, staat deze directory automatisch ingesteld op dezelfde directory als de webpagina (de directory ".").
Met archive kun je eventueel aangeven uit welk jar-archief je het applet wilt aanroepen, als je het applet daarin gestopt hebt.
Met width geef je de breedte op van het applet.
Met height geef je de hoogte op van het applet.
Verder kunnen er bovendien ook nog parameters worden meegegeven aan een applet door het gebruik van <param>-tags, die ieder een name- en een value-attribuut hebben.
Met name geef je de naam van de parameter op.
Met value geef je de waarde van de parameter op.
parametertags staan tussen een blok van applettags in. Ze hebben geen afsluitende tag.
In een applet kan een parameterwaarde worden opgevraagd met met getParameter(String), waarbij de string die je in moet vullen de naam van de op te vragen parameter is.

In Java zijn er een heleboel al bestaande klassen, die je kunt gebruiken voor je eigen programma. Deze klassen, die de API (Application Program Interface) genoemd worden, zijn verdeeld in groepen, de zogeheten packages. Net als bij objecten hebben packages een boomstructuur die via notatie met punten aan te roepen is. Een belangrijke hoofdpackage is java. Daar binnen bevinden zich o.a. de packages lang, applet en awt. De volledige notatie van deze packages is java.lang, java.applet en java.awt.
Zo is de klasse Applet onderdeel van de package java.applet. Voluit is dat dan java.applet.Applet. Je hoeft echter niet steeds opnieuw de volledige naam van zo'n klasse te noemen. Je kunt de packagenaam plus klassenaam ook één keer noemen aan het begin van de sourcecode, achter een statement import. Vervolgens kun je daarna ook de klassenaam noemen zonder package.
Je kunt bijvoorbeeld een Applet definiëren op deze manier:

public class MijnNieuweApplet extends java.applet.Applet
{

}

Maar het kan ook zo:

import java.applet.Applet;

public class MijnNieuweApplet extends Applet
{

}

Het gebruik van import-opdrachten is vooral zinvol als je meerdere keren dezelfde klassenamen nodig hebt.
Wanneer je uit een hele package erg veel klassen nodig hebt, is het handig om de hele package in één keer te importeren. Dit kan met een sterretje * op de plaats van de klassenaam. Bijvoorbeeld:

import java.awt.*;

Alle klassen uit java.awt zijn dan direct aanroepbaar. Bij java.awt kan dit erg handig zijn, als je erg veel GUI-componenten gebruikt, zoals Label's, Button's, TextField's, Window's en nog veel meer.
De belangrijkste package die er is, java.lang, wordt overigens automatisch geïmporteerd. Dit hoef je niet meer te doen. Deze package bevat o.a. de klassen Object, Class, String, Math en System.

Dat JavaScript veel met Java te maken heeft wordt vooral duidelijk met het feit dat er communicatie mogelijk is met Java vanuit JavaScript.
Met JavaScript kun je namelijk de functies uit een applet aanroepen, alsof het gewoon JavaScript-functies zijn. Als je in een applet-tag een name-attribuut definieert, kun je het applet aanroepen met het document-object, een punt en vervolgens de in het attribuut opgegeven naam. Dit is dan het object waarvan je de in de applet geprogrammeerde methoden kunt aanroepen.
Hier volgt een voorbeeld van een applet, waarin we een functie setLabel(String) schrijven die tekst in een Label-component plaatst, en een script dat deze functie gebruikt.
Het applet (TekstToner.java, compileer met de opdrachtregel javac TekstToner.java):
De pagina:
Een combinatie van Java en JavaScript kan dus erg handig zijn.
Verder zijn er ook nog browsers die zelfs rechtstreekse aanroep van Java-API ondersteunen, maar Internet Explorer zit daar niet bij.

Terug naar Inhoudsopgave


Slotwoord

Dit is het einde van deze JavaScript-tutorial. Gefeliciteerd als je hem helemaal doorlopen hebt! Je weet nu een stuk meer over JavaScript en programmeren. Er is, zoals je misschien wel zult begrijpen, nog veel meer om te weten over deze dingen, maar het is in ieder geval een perfecte basis om verder te gaan met programmeren. Met kennis van JavaScript is het niet erg moeilijk meer om ook andere talen te leren, zowel scripttalen als echte programmeertalen. Naast bijvoorbeeld de kort in deze tutorial besproken andere talen, VBScript en Java, kun je ook goed server-side talen zoals PHP, ASP of Perl gaan leren. Kortom, kennis van JavaScript bied je vele mogelijkheden!

Eduard de Jong

 
 

Valid XHTML 1.0 Transitional