# Zelfdocumenterende Code

Zelfdocumenterende code is een programmeerprincipe waarbij de code zelf voldoende informatie bevat om gemakkelijk te begrijpen en te onderhouden te zijn. Een krachtige techniek om zelfdocumenterende code te schrijven, is het gebruik van duidelijke namen voor variabelen, functies en methoden. Laten we dit principe toepassen op enkele refactoring-oefeningen.

# Overzicht van Technieken

# Structureel

# Functies

Verplaats code naar een functie voor duidelijkheid en hergebruik. Volgende code is correct, maar wat dit precies doet is niet duidelijk.

let width = (value - 0.5) * 16;
1

We schrijven beter de code in een functie met een duidelijke naam:

let width = emToPixels(value);

function emToPixels(ems) {
return (ems - 0.5) \* 16;
}
1
2
3
4
5

Vervang voorwaardelijke expressies door een functie voor meer duidelijke code.

if (!el.offsetWidth || !el.offsetHeight) {
    // je code hier
}
1
2
3

Door dit in een functie te schrijven kunnen we verduidelijken wat deze lijn doet.

function isVisible(el) {
  return el.offsetWidth && el.offsetHeight;
}
1
2
3

Een andere mogelijkheid is om de expressies door variabelen te vervangen voor duidelijkheid, vooral in specifieke algoritmen.

let isVisible = el.offsetWidth && el.offsetHeight;
if (!isVisible) {
    // je code hier
}
1
2
3
4

Een ander voorbeeld is:

return a * b + c / d;
1

Dit wordt dan:

let multiplier = a * b;

let divisor = c / d;
return multiplier + divisor;
1
2
3
4

# Klasses en modules

Definieer duidelijke klassen- en module-interfaces voor beter begrip van het gebruik.

class Box {
  setState(state) {
    this.state = state;
  }

  getState() {
    return this.state;
  }
}
1
2
3
4
5
6
7
8
9

Hierin is niet direct duidelijk hoe we deze klasse moeten gebruiken, we kunnen dit verduidelijken door te herschrijven naar:

class Box {
  open() {
    this.state = "open";
  }

  close() {
    this.state = "closed";
  }

  isOpen() {
    return this.state === "open";
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# Groeperen

Groepeer code logisch om relaties tussen verschillende delen aan te geven.

let foo = 1;
bar(foo);
quux(foo);

blah();
xyz();

baz(1337);
1
2
3
4
5
6
7
8

Maar beter is dus:

let foo = 1;
bar(foo);
quux(foo);

blah();
xyz();

baz(1337);
1
2
3
4
5
6
7
8

# Zuivere functies

Geef de voorkeur aan pure functies voor een duidelijker begrip en vermijd afhankelijkheid van de status.

Wat is een zuivere functie? Als je een functie aanroept met dezelfde parameters en deze altijd dezelfde uitvoer produceert, is het waarschijnlijk een zogenaamde “pure” functie. Dit betekent dat de functie geen neveneffecten mag hebben of afhankelijk mag zijn van toestand - zoals tijd, objecteigenschappen, Ajax, enz.

# Benaming

Het benoemen van functies en variabelen is vaak niet al te moeilijk, maar er zijn enkele eenvoudige regels die je kunt volgen:

# Functiebenamingen

  • Vermijd het gebruik van vage woorden zoals “handle” of “manage”: handleLinks(), manageObjects(). Wat doen deze functies precies?
  • Gebruik werkwoorden in de actieve vorm: cutGrass(), sendFile() - functies die actief iets uitvoeren.
  • Geef de retourwaarde aan: getMagicBullet(), readFile(). Dit is niet altijd mogelijk, maar het is nuttig waar het zinvol is.
  • Talen met sterke typering kunnen typehandtekeningen gebruiken om retourwaarden aan te geven.

# Variabelennamen

Bij variabelen zijn hier twee goede vuistregels:

  • Geef eenheden aan: als je numerieke parameters hebt, kun je de verwachte eenheid opnemen. Bijvoorbeeld, widthPx in plaats van width om aan te geven dat de waarde in pixels is in plaats van in een andere eenheid.
  • Gebruik geen afkortingen: a of b zijn geen acceptabele namen, behalve voor tellers in lussen.
let widthPx = ...
1

# Conventies

Volg vastgestelde benamingconventies voor consistentie.

let element = getElement();
1

In plaats van

let node = getElement();
1

# Fouten

Gebruik zinvolle foutmeldingen die het probleem beschrijven en relevante gegevens verstrekken.

throw new Error("Undefined is not an object!");
1

# Syntaxis

Vermijd syntactische trucs voor een betere leesbaarheid van de code.

imTricky && doMagic();
1

Wordt dan:

if (imTricky) {
  doMagic();
}
1
2
3

Gebruik constanten in plaats van magische waarden.

const MEANING_OF_LIFE = 42;
const PI = 3.14;
1
2

Vermijd boolean-vlaggen voor duidelijkere code.

myThing.setData({ x: 1 }, true);
1

Je moet al deze methode gaan bekijken om te weten wat dit doet, beter kunnen we schrijven:

myThing.mergeData({ x: 1 });
1

Maak gebruik van ingebouwde methodes om de communicatie van de codeintentie te verbeteren.

var ids = [];
for (var i = 0; i < things.length; i++) {
  ids.push(things[i].id);
}
1
2
3
4

Kan ook geschreven worden als:

let ids = things.map(function (thing) {
  return thing.id;
});
1
2
3

# Anti-patronen

  • Wees voorzichtig met het extraheren van functies uitsluitend vanwege de lengte, omdat dit de begrijpelijkheid van de code kan beïnvloeden.

  • Forceer technieken niet als ze niet geschikt lijken; er is geen one-size-fits-all benadering.

Naar: Self-Documenting JavaScript (opens new window)

© 2025 Arteveldehogeschool Laatst bijgewerkt: 3/12/2023 14:33:17