‘String’-object
Dit artikel legt het String-object uit.
De uitleg behandelt alles van de basis tot geavanceerde technieken, inclusief valkuilen met betrekking tot Unicode en reguliere expressies, stap voor stap en op een makkelijk te begrijpen manier.
YouTube Video
‘String’-object
Strings zijn in JavaScript een van de meest gebruikte types in dagelijkse ontwikkeling.
Verschil tussen primitieve strings en string-objecten
Primitieve strings (zoals "hello") gedragen zich anders dan wrapper-objecten zoals new String("hello"). Normaal gesproken moet je de primitieve vorm gebruiken en is er weinig noodzaak om de objectvorm te gebruiken.
1// Primitive string
2const a = "hello";
3
4// String wrapper object
5const b = new String("hello");
6
7console.log(typeof a); // "string"
8console.log(typeof b); // "object"
9console.log(a === b); // false — wrapper objects are not strictly equal
- Deze code toont het verschil in type tussen een primitieve string en een wrapper, en hoe ze zich gedragen bij strikte vergelijking. Vermijd in de meeste gevallen het gebruik van
new String()en gebruik de primitieve vorm.
Manieren om strings te maken (literal en template literals)
Template literals zijn handig voor het invoegen van variabelen en het schrijven van meerregelige strings. Je kunt variabelen invoegen en expressies op een intuïtieve manier evalueren.
1const name = "Alice";
2const age = 30;
3
4// Template literal
5const greeting = `Name: ${name}, Age: ${age + 1}`;
6
7console.log(greeting); // "Name: Alice, Age: 31"
- Template literals zijn zeer leesbaar en ideaal voor het bouwen van complexe strings, inclusief meerregelige strings.
Veelgebruikte methoden (zoeken en subtekst extractie)
Het String-object heeft veel basismethoden.
1const text = "Hello, world! Hello again.";
2
3// search
4console.log(text.indexOf("Hello")); // 0
5console.log(text.indexOf("Hello", 1)); // 13
6console.log(text.includes("world")); // true
7console.log(text.startsWith("Hello")); // true
8console.log(text.endsWith("again.")); // true
9
10// slice / substring
11console.log(text.slice(7, 12)); // "world"
12console.log(text.substring(7, 12)); // "world"
sliceensubstringlijken op elkaar, maar behandelen negatieve indexen verschillend.sliceinterpreteert negatieve waarden als posities vanaf het einde. Wees duidelijk over welke je gebruikt.
Splitsen en Samenvoegen (split / join)
Het is gebruikelijk om een string te splitsen in een array voor verwerking en deze daarna weer samen te voegen.
1const csv = "red,green,blue";
2const arr = csv.split(","); // ["red","green","blue"]
3
4console.log(arr);
5console.log(arr.join(" | ")); // "red | green | blue"
- Een veelvoorkomend patroon is een string opsplitsen met
split, de resulterende array verwerken metmapoffilter, en deze weer samenvoegen metjoin.
Vervangen en Reguliere Expressies
replace vervangt alleen de eerste overeenkomst. Als je alle overeenkomsten wilt vervangen, gebruik dan de g-vlag met een reguliere expressie. Door een functie als vervanger door te geven, kun je ook dynamische vervangingen uitvoeren.
1const s = "foo 1 foo 2";
2
3// replace first only
4console.log(s.replace("foo", "bar")); // "bar 1 foo 2"
5
6// replace all using regex
7console.log(s.replace(/foo/g, "bar")); // "bar 1 bar 2"
8
9// replace with function
10const r = s.replace(/\d+/g, (match) => String(Number(match) * 10));
11console.log(r); // "foo 10 foo 20"
- Met dynamische vervangingen via een functie kun je beknopte code schrijven die overeenkomsten analyseert en transformeert.
Hoofdlettergevoeligheid en normalisatie
Voor meertalige ondersteuning en vergelijking is naast toLowerCase en toUpperCase ook Unicode-normalisatie (normalize) belangrijk. Dit is vooral noodzakelijk bij het vergelijken van tekens met accenten.
1// Case conversion example:
2// "\u00DF" represents the German letter "ß".
3// In some locales, converting "ß" to uppercase becomes "SS".
4// JavaScript follows this behavior.
5console.log("\u00DF");
6console.log("\u00DF".toUpperCase()); // "SS"
7
8// Unicode normalization example:
9// "e\u0301" is "e" + a combining acute accent.
10// "\u00e9" is the precomposed character "é".
11// These two look the same but are different code point sequences.
12const a = "e\u0301";
13const b = "\u00e9";
14
15console.log(a === b); // false: different underlying code points
16console.log(a.normalize() === b.normalize()); // true: normalized to the same form
- Verschillende Unicode-representaties, zoals ligaturen en gecombineerde tekens, zijn niet als vanzelf gelijk, dus gebruik
normalize()voor het vergelijken.
Unicode en codepunten (omgaan met surrogaatparen)
JavaScript-strings zijn reeksen van UTF-16 code-eenheden, dus sommige tekens zoals emoji's kunnen twee code-eenheden voor één teken innemen. Om echte tekeneenheden te behandelen, gebruik Array.from, de spread-operator of for...of.
1// Emoji composed with multiple code points:
2// "\u{1F469}" = woman, "\u{200D}" = Zero Width Joiner (ZWJ),
3// "\u{1F4BB}" = laptop. Combined, they form a single emoji: 👩💻
4const s = "\u{1F469}\u{200D}\u{1F4BB}";
5console.log(s);
6
7// Length in UTF-16 code units (not actual Unicode characters):
8// Because this emoji uses surrogate pairs + ZWJ, the length may be > 1.
9console.log("Length:", s.length);
10
11// Iterate by Unicode code points (ES6 for...of iterates code points):
12// Each iteration gives a full Unicode character, not UTF-16 units.
13for (const ch of s) {
14 console.log(ch);
15}
16
17// Convert to an array of Unicode characters:
18console.log(Array.from(s));lengthgeeft het aantal code-eenheden terug, dus je krijgt mogelijk niet de verwachte telling bij emoji's of ligaturen.for...ofenArray.frombehandelen iets wat dicht bij weergegeven tekens ligt (grafemenclusters), maar als je volledige grafemenondersteuning nodig hebt, overweeg dan een gespecialiseerde bibliotheek.
Veilig vervangen met reguliere expressies (bij het verwerken van gebruikersinput)
Als je vergeet om gebruikersinvoer te escapen wanneer je deze in een reguliere expressie verwerkt, kan dit leiden tot onverwacht gedrag en kwetsbaarheden. Escape altijd gebruikersinput voordat je het in een patroon gebruikt.
1function escapeRegex(s) {
2 return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3}
4
5const userInput = "a+b";
6const pattern = new RegExp(escapeRegex(userInput), "g");
7console.log("a+b a+b".replace(pattern, "X")); // "X X"
- Gebruik gebruikersstrings nooit direct in reguliere expressies; escape ze altijd voordat je de regex maakt.
Prestatie-tips: concatenatie en templates
Bij het achter elkaar samenvoegen van veel kleine strings kan het efficiënter zijn om ze in een array te plaatsen en join te gebruiken. Aan de andere kant zijn template strings zeer leesbaar en in de meeste gevallen snel genoeg.
1// concatenation in loop (less ideal)
2let s = "";
3for (let i = 0; i < 1000; i++) {
4 s += i + ",";
5}
6
7// using array + join (often faster for many pieces)
8const parts = [];
9for (let i = 0; i < 1000; i++) {
10 parts.push(i + ",");
11}
12const s2 = parts.join("");- Moderne JavaScript-engines zijn zeer geoptimaliseerd, dus je hoeft je geen zorgen te maken over prestaties bij een klein aantal samenvoegingen. Moet je echter tienduizenden keren samenvoegen, dan kan het gebruik van
joinefficiënter zijn.
Handige praktische technieken: opvullen, trimmen en herhalen
trim, padStart, padEnd en repeat zijn handige methoden die vooral nuttig zijn bij alledaagse tekstverwerking. Ze worden vaak gebruikt in praktische situaties, zoals het formatteren van invoerwaarden of het standaardiseren van uitvoerformaten.
1console.log(" hello ".trim()); // "hello"
2console.log("5".padStart(3, "0")); // "005"
3console.log("x".repeat(5)); // "xxxxx"
- Deze methoden kunnen gebruikt worden om formulierinvoer te normaliseren of vaste-breedte-uitvoer te genereren.
Stringvergelijking (vergelijking op basis van lokale instellingen)
localeCompare is effectief voor het vergelijken van strings volgens de woordenboekvolgorde voor verschillende talen. Je kunt taal- en gevoeligheidsopties opgeven (zoals hoofdlettergevoeligheid).
1console.log(
2 "\u00E4".localeCompare("z", "de")
3); // may be -1 or other depending on locale
4
5console.log(
6 "a".localeCompare("A", undefined, { sensitivity: "base" })
7); // 0
- Gebruik voor geïnternationaliseerde vergelijkingen
localeCompareen geef de juiste taal en opties op.
Praktisch voorbeeld: een CSV-rij omzetten naar een object (praktische workflow)
Een veelvoorkomend gebruik is het parsen van een enkele CSV-rij naar een object met een combinatie van split, trim en map. Gebruik voor velden met aanhalingstekens of complexe CSV-bestanden een speciale CSV-parser.
1// simple CSV parse (no quotes handling)
2function parseCsvLine(line, headers) {
3 const values = line.split(",").map(v => v.trim());
4 const obj = {};
5 headers.forEach((h, i) => obj[h] = values[i] ?? null);
6 return obj;
7}
8
9const headers = ["name", "age", "city"];
10const line = " Alice , 30 , New York ";
11console.log(parseCsvLine(line, headers));
12// { name: "Alice", age: "30", city: "New York" }
- Deze methode werkt voor eenvoudige CSV, maar weet dat hij geen gevallen aankan waarbij een komma in een aanhalingstekensveld staat.
Veelvoorkomende valkuilen
Er zijn enkele gemakkelijk over het hoofd geziene specificaties en gedragingen in de stringverwerking in JavaScript. Om onverwachte bugs te voorkomen is het belangrijk de volgende punten in gedachten te houden.
- Het gebruik van
new String()kan tot onjuiste resultaten leiden bij typecontroles of vergelijkingen. In de meeste gevallen zijn primitieve stringtypes voldoende. - In Unicode kan een enkel zichtbaar teken uit meerdere code-eenheden bestaan. Daarom kan de waarde die door
lengthwordt teruggegeven, afwijken van het daadwerkelijke aantal weergegeven tekens. - Wanneer je gebruikersinput in een reguliere expressie opneemt, escape deze dan altijd eerst.
String.prototype.replace()vervangt standaard alleen de eerste overeenkomst. Als je alle voorkomens wilt vervangen, gebruik dan de/g-vlag in je reguliere expressie.- Strings zijn onveranderlijk, dus operaties leveren altijd een nieuwe string op. Het is belangrijk altijd de geretourneerde waarde toe te wijzen.
Samenvatting
Hoewel JavaScript-strings eenvoudig lijken, is het belangrijk hun eigenschappen wat betreft Unicode en onveranderlijkheid te begrijpen. Door de basis onder de knie te krijgen kun je de betrouwbaarheid en leesbaarheid van je stringverwerking aanzienlijk verbeteren.
Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.