JavaScript-objecten en JSON

Leer echte gegevens modelleren met JavaScript-objecten: maak en wijzig eigenschappen, doorloop ze en ontdek waarom het kopiëren van een variabele niet het object kopieert waarnaar die verwijst. Geef objecten gedrag met methoden en bepaal waarnaar het sleutelwoord this bij elke soort aanroep verwijst. Pak gegevens uit en combineer ze met destructurering, spreadsyntaxis en restsyntaxis, sla verzamelingen op in Map en Set en converteer gegevens naar JSON-tekst en terug met JSON.stringify en JSON.parse.

BeginnerLes 4 van 9 in Cursus JavaScript programmeren: DOM, events, asynchrone code en modules

Wat je leert

  1. Beschrijf echte zaken in code als objecten met benoemde eigenschappen, lees en wijzig die eigenschappen en begrijp hoe objecten worden opgeslagen, gekopieerd en vergeleken.
    • Maak objecten en werk met hun eigenschappen
      Schrijf objectliterals, lees eigenschappen met puntnotatie en blokhaaknotatie en voeg eigenschappen toe, wijzig ze en verwijder ze.
    • Controleer de eigenschappen van een object en doorloop ze met een lus
      Controleer of een eigenschap bestaat, maak lijsten van sleutels, waarden en sleutel-waardeparen en doorloop of transformeer de eigenschappen van een object.
    • Begrijp referenties, kopiëren en vergelijken
      Leg uit waarom objecten via referenties worden gedeeld, vergelijk objecten correct en maak oppervlakkige en diepe kopieën.
    • Werk met geneste gegevens
      Lees en verwerk objecten binnen objecten en arrays van objecten, vang ontbrekende onderdelen op met ?. en ?? en kies een structuur die bij de gegevens past.
  2. Schrijf methoden die de gegevens van hun object gebruiken, leg uit hoe het sleutelwoord this bij elke soort aanroep zijn waarde krijgt en behoud de juiste waarde van this wanneer je een methode doorgeeft.
    • Schrijf methoden die de gegevens van hun object gebruiken
      Definieer methoden met de verkorte notatie, gebruik this om het object te lezen en bij te werken en roep methoden correct aan.
    • Leg uit hoe this zijn waarde krijgt
      Bepaal de waarde van this aan de hand van de manier waarop een functie wordt aangeroepen en leg uit waarom pijlfuncties zich anders gedragen.
    • Behoud de waarde van this wanneer je methoden als callbacks doorgeeft
      Herken wanneer een methode haar object verliest en los dit op met een omhullende pijlfunctie, bind, call of apply.
  3. Haal waarden uit objecten en arrays met destructurering en kopieer, combineer en verzamel waarden met spreadsyntaxis en restsyntaxis.
    • Destructureer objecten
      Pak objecteigenschappen uit in variabelen, met hernoemen, standaardwaarden, geneste patronen en gedestructureerde functieparameters.
    • Destructureer arrays en andere itereerbare waarden
      Pak waarden uit op basis van hun positie, sla ze over of geef ze een standaardwaarde, verwissel variabelen en destructureer sleutel-waardeparen in lussen.
    • Kopieer, voeg samen en verzamel met spreadsyntaxis en restsyntaxis
      Gebruik spreadsyntaxis om objecten en arrays te kopiëren en samen te voegen en om arrayitems als argumenten door te geven, gebruik restsyntaxis om waarden te verzamelen en onderscheid de twee.
  4. Gebruik Map voor verzamelingen sleutel-waardeparen met sleutels van elk type en Set voor verzamelingen unieke waarden, en kies tussen deze structuren en gewone objecten en arrays.
    • Sla sleutel-waardeparen op in een Map
      Maak een Map en werk die bij, doorloop de sleutel-waardeparen, converteer tussen Maps en objecten en bepaal wanneer een Map beter past dan een object.
    • Bewaar unieke waarden in een Set
      Maak een Set en werk die bij, verwijder dubbele waarden uit arrays en vergelijk verzamelingen met verzamelingsoperaties.
  5. Lees en schrijf het JSON-tekstformaat, zet JavaScript-waarden met JSON.stringify om in JSON en JSON-tekst met JSON.parse terug in waarden, en handel gevallen af waarin de twee niet overeenkomen.
    • Lees en schrijf het JSON-formaat
      Herken geldige JSON, leg uit hoe JSON verschilt van een JavaScript-objectliteral en herken veelvoorkomende syntaxisfouten.
    • Zet waarden om in JSON-tekst met JSON.stringify
      Converteer objecten en arrays naar JSON-strings, maak de uitvoer op, kies welke eigenschappen worden opgenomen en voorspel wat wegvalt of verandert.
    • Zet JSON-tekst om in waarden met JSON.parse
      Ontleed JSON veilig, herstel waarden zoals datums met een herstelcallback, controleer de ontlede gegevens en converteer gegevens naar JSON en terug.

JavaScript-objecten en JSON: uitleg

5 hoofdstukken

1

Modelleer gegevens met objecten

Een object bewaart samenhangende waarden bij elkaar onder namen, zodat een record één boek, persoon of meting kan beschrijven. Met die namen kun je één veld wijzigen, een heel record bekijken en lijsten van records ordenen. Je volgt ook welke variabelen naar hetzelfde object verwijzen. Dat onderscheid is van belang wanneer een wijziging op twee plaatsen verschijnt, een kopie geneste gegevens bevat of een ontbrekend veld een zinvolle standaardwaarde nodig heeft.

1.1 Maak objecten en werk met hun eigenschappen

Een object groepeert samenhangende waarden onder namen. Elke eigenschap koppelt een sleutel aan een waarde. Gebruik één object voor een record en een array van objecten voor een geordende lijst. Parallelle arrays kunnen hun onderlinge samenhang verliezen als er maar één wordt gesorteerd of gewijzigd.

Maak en lees een record
const book = { title: "Dune", pages: 412, available: true };
book.title;    // "Dune"
book["title"]; // "Dune"

Eigenschapswaarden kunnen behalve primitieve waarden ook arrays, objecten of functies zijn. Sleutels zijn strings of symbolen; deze voorbeelden gebruiken strings. Stringsleutels die geldige identifiers zijn, hebben geen aanhalingstekens nodig. Sleutels met spaties of koppeltekens hebben die wel nodig: { "release-year": 1965 }. Numerieke sleutels worden strings, dus { 1: "a" } heeft de sleutel "1". Objectliterals staan een komma aan het einde toe.

Puntnotatie gebruikt de letterlijke naam na de punt. Blokhaaknotatie evalueert een expressie:

const field = "pages";
book[field]; // 412
book.field;  // undefined

De tweede expressie zoekt naar een eigenschap met de naam "field". Blokhaken zijn ook geschikt voor book["release-year"]. Een ontbrekende eigenschap geeft undefined terug; als je via die waarde verder leest, zoals in book.author.name, wordt een TypeError opgeworpen als author ontbreekt.

Wijzig de inhoud van het object
book.author = "Frank Herbert";
book.pages = 896;
delete book.available;

Een toewijzing voegt een ontbrekende eigenschap toe of vervangt een bestaande waarde. Verwijderen haalt de eigenschap zelf weg, dus "available" in book is nu onwaar. const houdt de variabele gekoppeld aan dit object, maar staat wijzigingen in de inhoud toe.

Voor const reading = { city: "Nairobi", tempC: 24.5 }; slaat reading.tempC += 1.5; de waarde 26 op. Daarna voegt reading.humidity = 61; een veld toe. Met const key = "humidity"; leest reading[key] de waarde 61. Een naam zoals tempC maakt de eenheid van de meting zichtbaar.

Gebruik variabelen in een literal
const name = "Lena";
const age = 29;
const person = { name, age };
const lang = "nl";
const greeting = { [lang]: "Hallo" };

De verkorte eigenschapsnotatie { name, age } betekent hetzelfde als { name: name, age: age }. Bij een berekende eigenschapsnaam wordt de expressie tussen blokhaken geëvalueerd: greeting heeft de eigenschap "nl". Zonder die blokhaken zou { lang: "Hallo" } de letterlijke sleutel "lang" aanmaken.

Belangrijkste punten

  • Een object groepeert samenhangende waarden in benoemde eigenschappen.
  • Gebruik blokhaken voor een sleutel die in een variabele is opgeslagen of een koppelteken bevat.
  • Een toewijzing voegt een eigenschap toe of vervangt die; delete verwijdert de eigenschap.
  • const legt de variabele vast, niet de inhoud van het object.
  • De verkorte eigenschapsnotatie neemt een variabelewaarde over; een berekende sleutel evalueert een expressie.

1.2 Controleer de eigenschappen van een object en doorloop ze met een lus

Controleren of een veld bestaat is iets anders dan de waarde ervan controleren. Een lege string, nul of false kan een volkomen geldige opgeslagen waarde zijn.

Stel de juiste vraag over aanwezigheid
const item = { stock: 0, note: undefined };
Object.hasOwn(item, "stock"); // true
"note" in item;                // true
Boolean(item.stock);          // false

Object.hasOwn(obj, key) controleert alleen de eigen eigenschappen van het object. De operator in controleert ook overgeërfde eigenschappen: "toString" in {} is true, terwijl Object.hasOwn({}, "toString") gelijk is aan false. Oudere code roept vaak obj.hasOwnProperty(key) aan.

Een voorwaarde zoals if (item.stock) controleert of de waarde truthy is. Ze kan geen onderscheid maken tussen een ontbrekend veld en een aanwezig veld met de waarde nul. Hetzelfde probleem geldt voor "", false, null, undefined en NaN. Zelfs een waarde undefined kan bij een bestaande eigenschap horen, zoals bij note hierboven.

Kies sleutels, waarden of paren

Voor const scores = { Ana: 82, Ben: 74, Chen: 91 }; geven deze functies arrays terug van eigen opsombare eigenschappen met strings als sleutels:

ExpressieResultaat
Object.keys(scores)["Ana", "Ben", "Chen"]
Object.values(scores)[82, 74, 91]
Object.entries(scores)[["Ana", 82], ["Ben", 74], ["Chen", 91]]

Het object heeft geen lengte zoals een array: scores.length is undefined. Object.keys(scores).length telt drie eigenschappen. Om de scores op te tellen, reduceer je de waarden met nul als beginwaarde. De som is 247 en het gemiddelde is ongeveer 82,33.

Doorloop met beide onderdelen beschikbaar
let bestName;
let bestScore = -Infinity;
for (const [name, score] of Object.entries(scores)) {
  if (score > bestScore) {
    bestName = name;
    bestScore = score;
  }
}

De lus vergelijkt achtereenvolgens 82, 74 en 91 met de hoogste score tot dan toe. De lus eindigt met "Chen" en 91. Het patroon met blokhaken geeft namen aan de twee onderdelen van elk paar.

Een gewoon object is niet itereerbaar, dus for...of scores werpt een TypeError op. Object.entries(scores) levert een itereerbare array. De oudere for...in-lus levert stringsleutels op en kan overgeërfde opsombare eigenschappen bevatten.

Zet sleutel-waardeparen weer om in een object
const weightsG = { flour: 500, sugar: 250, salt: 5 };
const weightsKg = Object.fromEntries(
  Object.entries(weightsG).map(([item, g]) => [item, g / 1000])
);

entries levert paren op, map wijzigt elke waarde met behoud van de sleutel en fromEntries bouwt het record opnieuw op. Het resultaat is { flour: 0.5, sugar: 0.25, salt: 0.005 }; weightsG blijft ongewijzigd.

De volgorde van eigen eigenschappen ligt vast. Array-indexsleutels van "0" tot en met "4294967294" verschijnen eerst in oplopende volgorde; andere stringsleutels volgen de invoegvolgorde. Een voorloopnul, zoals in "01", voorkomt dat een sleutel een array-index is. Zo geeft Object.keys({ b: 1, 2: "x", a: 2, 1: "y" }) de array ["1", "2", "b", "a"]. Gebruik een array als posities betekenis hebben.

Belangrijkste punten

  • Of een eigenschap bestaat en of haar waarde truthy is, zijn verschillende vragen.
  • Object.hasOwn controleert eigen eigenschappen; in controleert ook overgeërfde eigenschappen.
  • Object.entries levert sleutel-waardeparen voor lussen en transformaties.
  • Object.fromEntries bouwt een object opnieuw op uit paren.
  • Array-indexsleutels komen in de eigenschapsvolgorde vóór andere stringsleutels.
  • Tel eigen opsombare stringsleutels met Object.keys(obj).length.

1.3 Begrijp referenties, kopiëren en vergelijken

Twee variabelen kunnen naar één object verwijzen. Voordat je een wijziging voorspelt, bepaal je of de code een nieuw object heeft gemaakt of een referentie naar een bestaand object heeft gekopieerd.

Volg identiteit los van gegevens
const p1 = { x: 1 };
const p2 = p1;
p2.x = 99;
p1.x;       // 99
p1 === p2;  // true

De toewijzing heeft de referentie gekopieerd. Beide namen bereiken dezelfde eigenschap. Toewijzing van primitieve waarden werkt anders: na let a = 5; let b = a; b = 6; blijft a gelijk aan 5.

Objecten worden zowel met === als met == op identiteit vergeleken. Twee literals maken afzonderlijke objecten aan, ook als alle velden overeenkomen: ({ x: 1 } === { x: 1 }) is false. Om hun gegevens te vergelijken, vergelijk je de relevante eigenschappen. Een overeenkomstige weergave is geen controle op identiteit.

Als je een object aan een functie doorgeeft, wordt de referentie ook gekopieerd. Een functie die order.status = "shipped"; uitvoert, wijzigt het object van de aanroeper. Als de functie in plaats daarvan { ...order, status: "shipped" } teruggeeft, maakt ze een nieuw record op het hoogste niveau aan.

Onderscheid const, bevriezen en kopiëren

const cart = { items: 2 }; staat cart.items = 3; toe, maar de hertoewijzing cart = {}; werpt een TypeError op. Object.freeze(cart) blokkeert wijzigingen in de eigen eigenschappen. In strikte modus werpen pogingen om die toe te voegen, te verwijderen of te overschrijven een TypeError op.

Bevriezen is oppervlakkig. Als een bevroren record een ander object bevat, kunnen de velden van dat geneste object nog steeds veranderen. Een bevroren container en een diepgaand onveranderlijke structuur zijn verschillende dingen.

Volg een oppervlakkige kopie
const settings = { theme: "dark", font: { size: 14 } };
const copy = { ...settings };
copy.theme = "light";
copy.font.size = 18;

Spreadsyntaxis maakt een nieuw buitenste object. De waarde van theme wordt gekopieerd, dus als je copy.theme wijzigt, blijft settings.theme gelijk aan "dark". De waarde van font is een referentie die naar beide records wordt gekopieerd. Als je copy.font.size bijwerkt, wordt settings.font.size daarom ook 18.

Object.assign({}, settings) maakt ook een oppervlakkige kopie. Een oppervlakkige kopie maakt een afzonderlijk buitenste record, terwijl de identiteit van geneste objecten en arrays behouden blijft.

Kopieer geneste gegevens wanneer ze onafhankelijk moeten zijn
const deep = structuredClone(settings);
deep.font.size = 22;
settings.font.size; // 18

structuredClone kopieert geneste objecten en arrays, samen met ondersteunde waarden zoals Map, Set en Date. De functie verwerkt ook circulaire referenties. De nieuwe geneste font kan onafhankelijk veranderen. Functies kunnen niet op deze manier worden gekloond: een object met een methode veroorzaakt een DataCloneError.

Een heen-en-terugconversie via JSON, JSON.parse(JSON.stringify(obj)), kopieert alleen gegevens die geschikt zijn voor JSON. Eigenschappen met undefined of functies vallen weg, datums worden strings en sleutel-waardeparen van Map en waarden van Set gaan verloren tenzij je ze converteert. Kies een kloon voor onafhankelijke, ondersteunde JavaScript-gegevens en kies JSON als je een tekstweergave wilt maken.

Belangrijkste punten

  • Toewijzingen en functieaanroepen kopiëren objectreferenties.
  • Objecten worden op identiteit vergeleken, ook als hun velden overeenkomen.
  • Een oppervlakkige kopie deelt geneste objecten.
  • Object.freeze blokkeert wijzigingen in eigen eigenschappen, maar werkt oppervlakkig.
  • structuredClone kopieert ondersteunde geneste gegevens en kan geen functies kopiëren.

1.4 Werk met geneste gegevens

Geneste gegevens combineren records en lijsten. Lees een pad stap voor stap en controleer of elke stap uitkomt bij een object, een array of een eindwaarde.

Lees en verwerk een lijst binnen een record
const order = {
  id: 1042,
  customer: { name: "Sara", city: "Lisbon" },
  items: [
    { product: "Tea", qty: 2, unitPrice: 4.5 },
    { product: "Mug", qty: 1, unitPrice: 9 }
  ]
};

order.customer.city leest "Lisbon". order.items[1].product selecteert eerst de array met items, dan het tweede record daarvan en vervolgens "Mug". order.items.length is 2.

De arraymethoden die je al kent, werken met eigenschappen van records. map(item => item.product) levert productnamen op. filter(item => item.qty > 1) behoudt de regel met thee. find(item => item.product === "Mug") geeft het bestaande record van de mok terug, dus als je dat teruggegeven record wijzigt, verandert het item in de bestelling.

Om het totaal te berekenen, gebruik je order.items.reduce((sum, item) => sum + item.qty * item.unitPrice, 0). De eerste regel telt 9 erbij op; de tweede telt er nog eens 9 bij op, wat 18 oplevert. Door een totaal te berekenen wanneer het nodig is, voorkom je dat een afzonderlijk opgeslagen totaal veroudert als items veranderen.

Lees optionele gegevens met een terugvaloptie
order.shipping?.date;                 // undefined
order.customer?.city ?? "unknown";    // "Lisbon"

Optionele ketenvorming, ?., stopt wanneer de waarde direct links ervan null of undefined is. Een directe order.shipping.date zou een TypeError opwerpen. Controleer elke optionele schakel in een langer pad. Blokhaaknotatie en aanroepen ondersteunen dit ook: order.items?.[0] en order.print?.().

Optionele ketenvorming is bedoeld voor waarden die mogen ontbreken. Verplichte velden hebben nog steeds controles of fouten nodig die een onjuist record zichtbaar maken. Optionele ketenvorming kan niet links van een toewijzing staan: order.shipping?.date = "2026-05-01" is een syntaxisfout.

De operator ?? voor terugval bij null of undefined gebruikt de rechterkant alleen bij null of undefined. De operator behoudt nul, false en "". Bij const qty = 0; blijft qty ?? 1 nul, terwijl qty || 1 de waarde 1 wordt omdat || elke falsy-waarde vervangt.

Kies een bruikbare structuur

Een array van records is geschikt om gegevens weer te geven, te filteren en te ordenen. Een object met ID's als sleutels maakt rechtstreeks opzoeken mogelijk: usersById["u23"].name. Een Map is nuttig wanneer opzoeksleutels vaak worden toegevoegd en verwijderd.

Nieuwer JavaScript biedt Object.groupBy, dat sinds 2024 breed beschikbaar is:

const tasks = [
  { title: "Book flights", status: "done" },
  { title: "Pack", status: "todo" },
  { title: "Renew passport", status: "done" }
];
const grouped = Object.groupBy(tasks, task => task.status);

grouped.done bevat twee records en grouped.todo bevat er één. Het resultaat heeft geen prototype en dus geen overgeërfde methode toString. Een ouder alternatief bouwt de arrays voor deze statussleutels expliciet op:

const groupedOlder = tasks.reduce((groups, task) => {
  if (!Object.hasOwn(groups, task.status)) {
    groups[task.status] = [];
  }
  groups[task.status].push(task);
  return groups;
}, {});

Het eerste record in elke groep maakt de bijbehorende array aan. Latere records worden aan diezelfde array toegevoegd. Deze accumulator is een gewoon object; het resultaat van de nieuwere methode heeft geen prototype. Gebruik consistente namen en waardetypen in alle records; namen zoals distanceKm en tempC houden ook eenheden zichtbaar.

Belangrijkste punten

  • Lees een genest pad vanaf het buitenste object naar de benodigde waarde.
  • find geeft het bestaande record terug, geen kopie.
  • ?. stopt bij een schakel met null of undefined; ?? biedt dan een terugvaloptie.
  • Gebruik een array voor een geordende lijst en gegevens met sleutels om rechtstreeks op te zoeken.
  • Object.groupBy groepeert records in arrays onder sleutels.
  • Consistente veldnamen, typen en eenheden maken records eenvoudiger te verwerken.
2

Geef objecten gedrag met methoden en this

Met methoden kan een object zijn gegevens combineren met acties die die gegevens gebruiken. Het korte woord this verbindt een actie met een object, maar de waarde ervan hangt af van hoe de functie wordt uitgevoerd. Je volgt gewone methodeaanroepen, geleende methoden en callbacks en kiest vervolgens een omhullende functie of een gebonden functie wanneer een actie haar object moet behouden. De voorbeelden worden als modules uitgevoerd, dus geldt de strikte modus tenzij een voorbeeld expliciet niet-strikte code gebruikt.

2.1 Schrijf methoden die de gegevens van hun object gebruiken

Een methode is een eigenschap met een functie als waarde, die via een object wordt aangeroepen. Daarmee kan een actie de huidige gegevens van het record gebruiken.

Schrijf een methode met this
const counter = {
  count: 0,
  increment() {
    this.count += 1;
    return this.count;
  }
};
counter.increment(); // 1
counter.increment(); // 2

De verkorte notatie increment() { ... } definieert een eigenschap met een gewone functie als waarde. In counter.increment() wordt het ontvangende object counter de waarde van this. Elke aanroep leest de opgeslagen telling, telt er één bij op en geeft het nieuwe getal terug.

Een losse count selecteert een variabele, niet de eigenschap. Zonder bijbehorende variabele werpt count += 1 een ReferenceError op. Gebruik this.count om het veld van het ontvangende object te bereiken.

Lees een functie of voer die uit

counter.increment leest een waarde van het type "function". De haakjes in counter.increment() voeren de functie uit en geven de retourwaarde. Wanneer je een actie doorgeeft voor later gebruik, heeft de ontvangende code de functie nodig en niet het resultaat van een uitvoering op dat moment.

Ingebouwde methoden gebruiken deze aanroepvorm ook: Math.max(3, 7) geeft 7 terug en "abc".toUpperCase() geeft "ABC" terug.

Hergebruik een actie
function describe() {
  return this.name + " (" + this.year + ")";
}
const film = { name: "Up", year: 2009, describe };
const song = { name: "Hello", year: 2015, describe };

film.describe() geeft "Up (2009)" terug; song.describe() geeft "Hello (2015)" terug. Met this kan dezelfde functie beide ontvangende objecten lezen. Als je film.name vast in de code zou schrijven, zou je de functie aan de variabele film binden.

Geef het ontvangende object terug voor een volgende actie
const playlist = {
  tracks: [],
  add(title) { this.tracks.push(title); return this; },
  count() { return this.tracks.length; }
};
playlist.add("Rain").add("Waves").count(); // 2

Elke aanroep van add geeft de afspeellijst terug, zodat de volgende methode op dat object kan worden opgezocht. Als add een getal zou teruggeven, zou de keten breken omdat de volgende add op dat getal zou worden opgezocht.

Gewone JSON-conversie laat methoden weg: bij het omzetten van { name: "Kit", hi() { return 1; } } naar een string wordt alleen name geschreven. Ontleden kan weggelaten code niet herstellen. Records voor opslag of uitwisseling bevatten vaak gewone gegevens en gebruiken afzonderlijke verwerkingsfuncties.

Belangrijkste punten

  • Een methode is een eigenschap met een functie als waarde, die via een object wordt aangeroepen.
  • In obj.method() gebruikt een gewone methode obj als this.
  • Een functiewaarde en het resultaat van de aanroep ervan zijn verschillende waarden.
  • Door this terug te geven, kan er nog een methodeaanroep volgen.
  • Gewone JSON-conversie laat eigenschappen met een functie als waarde weg.

2.2 Leg uit hoe this zijn waarde krijgt

Bij een gewone functie bepaalt de aanroep this. Een functie in een object opslaan verbindt die niet blijvend aan dat object.

Volg het ontvangende object bij de aanroep
const a = { n: "A", who() { return this.n; } };
const b = { n: "B" };
b.who = a.who;
a.who(); // "A"
b.who(); // "B"

Beide eigenschappen bevatten dezelfde functie. Het ontvangende object vóór de punt verschilt, dus verschillen de resultaten. De oorspronkelijke plaats van de functie bepaalt niet welk object de functie leest.

Bij een gewone aanroep, f(), levert de strikte modus undefined als this. JavaScript-modules worden altijd in strikte modus uitgevoerd; een script of functie kan ook beginnen met "use strict";. Een niet-strikte gewone functie die op deze manier wordt aangeroepen, gebruikt in plaats daarvan het globale object globalThis. In een browser is dat globale object window.

Herken de omringende context van een pijlfunctie

Een pijlfunctie heeft geen eigen this. Ze behoudt de this van de omringende code waar ze is gemaakt. Een objectliteral maakt geen nieuwe this-context aan.

// At the top level of a module:
const user = {
  name: "Ida",
  hi: () => "Hi, " + this.name
};

De aanroep user.hi() werpt een TypeError op: de pijlfunctie heeft de this van het hoogste niveau van de module vastgelegd, en die is undefined. Als je de aanroep op een methodeaanroep laat lijken, krijgt de pijlfunctie geen nieuw ontvangend object. Op het hoogste niveau van een klassiek script is de omringende this in plaats daarvan het globale object.

Gebruik een gewone methode wanneer de actie het aanroepende object nodig heeft. Gebruik een pijlfunctie binnen die methode wanneer een callback de context van de methode moet behouden:

const group = {
  title: "Team",
  members: ["Ana", "Ben"],
  list() {
    return this.members.map(m => this.title + ": " + m);
  }
};
group.list(); // ["Team: Ana", "Team: Ben"]

list krijgt group via de methodeaanroep. De pijlfunctie wordt binnen die uitgevoerde methode gemaakt en behoudt dezelfde this. Een strikte gewone callback zonder opgegeven ontvangend object zou undefined ontvangen, zodat this.title daar zou mislukken.

Gebruik een beslisvolgorde

Als je een aanroep tegenkomt, bepaal dan eerst welke functie wordt aangeroepen:

  1. Een pijlfunctie behoudt de omringende this; call, apply en bind kunnen die niet vervangen.
  2. Een gebonden gewone functie behoudt de gebonden this, ook bij gebruik van call of apply.
  3. Een ongebonden gewone functie die met call of apply wordt aangeroepen, gebruikt de opgegeven this.
  4. Een gewone aanroep obj.method() gebruikt obj.
  5. Een gewone functieaanroep gebruikt undefined in strikte modus of het globale object in niet-strikte modus.

Callbacks kunnen een ontvangend object krijgen van de code die ze aanroept. Zo krijgt een gewone DOM-eventlistener die met addEventListener is geregistreerd, het element waarop die is geregistreerd als this. Bekijk hoe de ontvangende code een callback aanroept voordat je aanneemt dat het een gewone functieaanroep is.

Belangrijkste punten

  • Een gewone functie krijgt this via de aanroep, dus als je een methode leent, verandert het ontvangende object.
  • Een gewone functieaanroep in strikte modus gebruikt undefined als this.
  • Een pijlfunctie behoudt de omringende this van de plaats waar ze is gemaakt.
  • Een gebonden ontvangend object heeft voorrang op een latere call of apply.
  • Een pijlfunctie binnen een gewone methode kan de this van die methode behouden.

2.3 Behoud de waarde van this wanneer je methoden als callbacks doorgeeft

Als je een methode uit haar object haalt, blijft de functie behouden, maar gaat de oorspronkelijke aanroepexpressie verloren. Een callback moet zo worden aangeroepen dat die het benodigde object krijgt.

Onderzoek een losgekoppelde methode
const counter = {
  count: 0,
  increment() {
    this.count += 1;
    return this.count;
  }
};
const inc = counter.increment;
inc(); // TypeError in strict mode

inc() is een gewone functieaanroep, dus is this gelijk aan undefined. Het lezen van this.count mislukt voordat de telling kan worden verhoogd. In niet-strikte code gebruikt een gewone aanroep het globale object en kan die in plaats daarvan een globale count beschrijven; de aanroep bereikt de teller niet.

Hetzelfde probleem doet zich voor bij arraycallbacks. [1, 2].map(counter.increment) geeft een functie aan map zonder het oorspronkelijke ontvangende object. De arraywaarden die als argumenten worden doorgegeven, leveren geen this.

Omhul de methodeaanroep
const results = [1, 2].map(() => counter.increment());
// results is [1, 2]; counter.count is 2

De callback is een pijlfunctie die een gewone aanroep counter.increment() uitvoert. Die aanroep heeft een ontvangend object. De omhullende functie negeert bewust de waarden die map doorgeeft; elke aanroep verhoogt de teller één keer. Deze vorm is handig wanneer de callback maar op één plaats nodig is.

Bind een herbruikbare functie

Begin met een nieuwe teller op nul:

const boundInc = counter.increment.bind(counter);
const results = [1, 2].map(boundInc);
// results is [1, 2]; counter.count is 2

bind geeft een nieuwe functie terug; de methode wordt nog niet aangeroepen. De nieuwe functie behoudt counter als ontvangend object. Als je de functie opnieuw aan een ander object bindt, kun je dat ontvangende object niet vervangen. Elke aanroep van bind maakt een afzonderlijke functie, dus bewaar het resultaat wanneer code later precies dezelfde callback moet herkennen.

Binden kan ook vooraanstaande argumenten vastleggen. Met function multiply(a, b) { return a * b; } gevolgd door const double = multiply.bind(null, 2); geeft double(21) de waarde 42 terug. null vult de positie voor het ontvangende object omdat deze functie geen this gebruikt; 2 vult de eerste gewone parameter.

Voer één keer uit met call of apply
function describe(unit) {
  return this.value + " " + unit;
}
describe.call({ value: 12 }, "kg");    // "12 kg"
describe.apply({ value: 12 }, ["kg"]); // "12 kg"

Beide vormen worden direct uitgevoerd met het gekozen ontvangende object. call geeft argumenten afzonderlijk door; apply geeft ze door in een array. De context van een pijlfunctie ligt vast door de omgeving, dus kunnen deze methoden de this van een pijlfunctie niet vervangen.

Als je counter.increment() als callback doorgeeft, wordt de methode direct uitgevoerd en het teruggegeven getal doorgegeven. Dat is niet de functie die map nodig heeft. Bij een eventregistratie zoals button.addEventListener("click", counter.increment()) verandert de teller direct en veroorzaakt de numerieke listener een TypeError. Geef een functiewaarde, een omhullende pijlfunctie of een opgeslagen gebonden functie door.

Belangrijkste punten

  • Als je een methode loskoppelt, verliest die haar oorspronkelijke ontvangende object.
  • Een omhullende pijlfunctie kan de benodigde methodeaanroep later uitvoeren.
  • bind maakt een functie met een vast ontvangend object en optionele vooraanstaande argumenten.
  • call en apply worden direct uitgevoerd; de vorm van hun argumenten verschilt.
  • Argumenten die als callback dienen, moeten functies zijn en niet het numerieke resultaat van een methodeaanroep.
3

Pak gegevens uit en combineer ze met destructurering, spreadsyntaxis en restsyntaxis

Met destructurering geef je namen aan geselecteerde onderdelen van een object of een geordende verzameling. Met spreadsyntaxis bouw je waarden op uit bestaande onderdelen, terwijl restsyntaxis de overgebleven onderdelen verzamelt. Deze vormen komen vaak samen voor in functies die opties ontvangen of bijgewerkte records teruggeven. Door goed naar hun positie te kijken, kun je voorspellen welke variabelen bestaan, welke standaardwaarden gelden en of geneste gegevens met het origineel worden gedeeld.

3.1 Destructureer objecten

Met objectdestructurering lees je benoemde velden in lokale variabelen. Je selecteert waarden zonder het hele bronrecord te kopiëren.

Koppel en hernoem
const book = { title: "Dune", pages: 412 };
const { pages, title: bookTitle, rating: stars = 0 } = book;

De koppeling gebruikt eigenschapsnamen, niet hun volgorde. Hiermee wordt pages gedeclareerd met de waarde 412, bookTitle met "Dune" en stars met 0. Er wordt geen variabele title of rating gedeclareerd: de naam na een dubbele punt is de lokale doelvariabele.

Een ontbrekend veld levert undefined op. Een standaardwaarde vervangt alleen undefined en behoudt null, nul, false en lege strings. const { a = 5 } = { a: null }; laat a daarom op null staan.

Volg geneste velden
const data = {
  location: { name: "Oslo" },
  current: { tempC: -3, windKph: 18 }
};
const {
  location: { name },
  current: { tempC, windKph: wind }
} = data;

De gedeclareerde variabelen zijn name, tempC en wind, met de waarden "Oslo", -3 en 18. De omhullende namen location en current selecteren paden; ze worden niet ook variabelen.

Als een buitenste object ontbreekt, mislukt het lezen van een geneste waarde. const { shipping: { date } } = {}; werpt een TypeError op. Geef een standaardwaarde voor het buitenste niveau als dat veld undefined kan zijn:

const { shipping: { date } = {} } = {};
// date is undefined

Dit vervangt shipping niet als de waarde null is. Als je null of undefined rechtstreeks destructureert, wordt ook een fout opgeworpen, dus moet de bron bruikbaar zijn voordat het uitpakken begint.

Ontvang benoemde opties
function formatUser({ name, age = "unknown" }) {
  return name + ", " + age;
}

formatUser({ name: "Mo" }) geeft "Mo, unknown" terug. Als je de velden herschikt zoals in { age: 40, name: "Ines" }, krijg je nog steeds "Ines, 40" terug. Een aanroep van formatUser zonder argument mislukt omdat er geen object is om uit te pakken. Een standaardwaarde voor de hele parameter maakt die aanroep mogelijk:

function greet({ name = "guest" } = {}) {
  return "Hi, " + name;
}
greet(); // "Hi, guest"

De buitenste standaardwaarde vangt een weggelaten argument op; de binnenste vangt een ontbrekende naam op. Als je null doorgeeft, mislukt het nog steeds. Om waarden aan bestaande variabelen toe te wijzen, zet je een instructie met een objectpatroon tussen haakjes: let x, y; ({ x, y } = { x: 4, y: 7 });. Anders worden de eerste accolades gelezen als een instructieblok.

Belangrijkste punten

  • Objectpatronen koppelen eigenschappen op naam.
  • Een dubbele punt hernoemt de variabele; de bronsleutel verandert niet.
  • Standaardwaarden vervangen undefined, ook bij ontbrekende eigenschappen, en behouden null.
  • Geneste patronen hebben op elk niveau een bruikbaar object nodig.
  • Een standaardwaarde voor de hele parameter en een standaardwaarde voor een eigenschap vangen verschillende ontbrekende waarden op.
  • Met haakjes kan een objectpatroon waarden toewijzen aan bestaande variabelen.

3.2 Destructureer arrays en andere itereerbare waarden

Arraydestructurering leest waarden op positie uit een itereerbare waarde. Komma's bepalen welke waarden worden geselecteerd; de variabelenamen kiezen de posities niet.

Selecteer of sla posities over
const medals = ["gold", "silver", "bronze"];
const [first, second] = medals;
const [, , third] = medals;

De variabelen krijgen "gold", "silver" en "bronze". Lege plaatsen nemen waarden in zonder variabelen te declareren. Een naam voorbij de beschikbare waarden krijgt undefined. Standaardwaarden vervangen alleen undefined:

const [p, q = 10] = [1]; // p is 1; q is 10
const [r = 10] = [null]; // r is null
Verzamel de overige waarden
const [head, ...tail] = [1, 2, 3, 4];
// head is 1; tail is [2, 3, 4]

Het laatste rest-element maakt een nieuwe array, die leeg is als er niets overblijft. Het moet als laatste staan. Eventuele objectwaarden in die array behouden hun identiteit; ze worden door het verzamelen niet diep gekloond.

Lees een teruggegeven paar of verwissel variabelen
function minMax(nums) {
  return [Math.min(...nums), Math.max(...nums)];
}
const [lo, hi] = minMax([4, 9, 1]);
// lo is 1; hi is 9

De aanroeper volgt de volgorde die de functie bij het teruggeven gebruikt. Bij veel resultaatvelden voorkomen benoemde objecteigenschappen dat je posities moet onthouden.

Met let x = 1, y = 2; verwisselt [x, y] = [y, x]; de variabelen. De array aan de rechterkant wordt vóór beide toewijzingen geëvalueerd als [2, 1], zodat beide oude waarden behouden blijven zonder tijdelijke variabele.

Pak andere itereerbare waarden uit

Strings en Sets kun je ook uitpakken: const [initial] = "Zoe"; geeft "Z". Sets leveren waarden in invoegvolgorde. Items van een Map zijn geordende paren:

const distances = new Map([["park", 2], ["lake", 5]]);
for (const [place, distanceKm] of distances) {
  console.log(place, distanceKm);
}

De lus ontvangt een paar, waarna het patroon de sleutel en waarde scheidt. Object.entries levert dezelfde paarstructuur.

Een gewoon object is niet itereerbaar, dus werpt const [name] = { name: "Ana" }; een TypeError op. Gebruik accolades om het benoemde veld te selecteren: const { name } = { name: "Ana" };. Blokhaken vereisen een reeks waarden; accolades selecteren eigenschappen op naam.

Belangrijkste punten

  • Arraypatronen koppelen op positie en lege plaatsen slaan waarden over.
  • Een ontbrekende positie wordt undefined, tenzij een standaardwaarde die vervangt.
  • Een rest-element aan het einde verzamelt de overige waarden in een nieuwe array.
  • Arraypatronen werken ook op strings, Sets en sleutel-waardeparen van Maps.

3.3 Kopieer, voeg samen en verzamel met spreadsyntaxis en restsyntaxis

De drie punten, ..., hebben twee verwante taken. Spreadsyntaxis vouwt bestaande gegevens uit in een waarde of aanroep. Restsyntaxis verzamelt waarden in een variabele waar een patroon of parameter die declareert.

Voeg samen in volgorde van prioriteit
const defaults = { lang: "en", units: "metric", alerts: true };
const user = { lang: "pt", alerts: false };
const options = { ...defaults, ...user };
// { lang: "pt", units: "metric", alerts: false }

Spreadsyntaxis voor objecten kopieert eigen opsombare eigenschappen. Als een sleutel opnieuw voorkomt, krijgt de latere waarde voorrang. Als je user vóór defaults plaatst, worden de instellingen van de gebruiker overschreven. Als je null of undefined met spreadsyntaxis in een object opneemt, wordt niets toegevoegd.

Kopieën met spreadsyntaxis zijn oppervlakkig. Als een genest record verandert, kopieer dan ook dat niveau:

const settings = { theme: "dark", font: { size: 14, family: "serif" } };
const next = {
  ...settings,
  font: { ...settings.font, size: 18 }
};

De buitenste spreadsyntaxis behoudt theme. De binnenste behoudt family en vervangt size. settings.font.size blijft 14 omdat het gewijzigde geneste record nieuw is.

Vervang één record in een lijst
const todos = [{ id: 1, done: false }, { id: 2, done: false }];
const updated = todos.map(t =>
  t.id === 2 ? { ...t, done: true } : t
);

map maakt een nieuwe array. Het overeenkomende item wordt een nieuw object, dus is updated[1].done waar terwijl todos[1].done onwaar blijft. Het ongewijzigde eerste item wordt opnieuw gebruikt: updated[0] === todos[0] is waar. Voor onafhankelijke bijwerkingen hoef je ongewijzigde records niet te kopiëren.

Vouw itereerbare waarden uit

In een arrayliteral of functieaanroep haalt spreadsyntaxis waarden uit een itereerbare waarde. [...a, ...b] voegt de waarden samen in een nieuwe array. Math.max(...[4, 9, 1]) geeft drie argumenten door en geeft 9 terug. Een gewoon object kan niet in een array worden uitgevouwen: [...{ a: 1 }] werpt een TypeError op. Spreadsyntaxis voor objecten en voor itereerbare waarden gebruikt verschillende regels voor wat wordt gelezen.

Verzamel argumenten of resterende eigenschappen
function total(...nums) {
  return nums.reduce((sum, n) => sum + n, 0);
}
total(2, 3, 5); // 10
total();        // 0

Een restparameter ontvangt een echte array, ook als die geen waarden ontvangt. De restparameter moet de laatste parameter zijn en er kan er maar één zijn. Het oudere arguments-object is geen echte array. Pijlfuncties hebben geen eigen arguments, maar kunnen wel de binding van een omringende gewone functie lezen.

Restsyntaxis voor objecten verzamelt eigen opsombare eigenschappen die nog niet zijn geselecteerd:

const userRecord = { id: 8, name: "Rae", password: "x9!k" };
const { password, ...publicUser } = userRecord;
// publicUser is { id: 8, name: "Rae" }

Dit maakt een nieuw record en laat de bron ongewijzigd. De rest-eigenschap moet als laatste staan. Kijk naar de plaats om de taken te onderscheiden: drie punten in een literal of aanroep vouwen waarden uit; drie punten in een parameterlijst of destructureringsdoel verzamelen waarden.

Belangrijkste punten

  • Bij overlappende eigenschappen in spreadsyntaxis voor objecten krijgt de latere eigenschap voorrang.
  • Kopieer elk genest niveau dat onafhankelijk moet veranderen.
  • Spreadsyntaxis in arrays en aanroepen heeft een itereerbare waarde nodig.
  • Restsyntaxis verzamelt resterende argumenten, items of eigenschappen en moet als laatste staan.
  • Een bijwerking met map kan een gewijzigd record kopiëren en ongewijzigde records opnieuw gebruiken.
  • Restparameters zijn echte arrays; het oudere arguments-object is dat niet.
4

Sla verzamelingen op met Map en Set

Sommige verzamelingen hebben sleutels nodig die objecten of getallen zijn, en andere moeten elke waarde maar één keer bewaren. Map en Set drukken die behoeften rechtstreeks uit. Je maakt sleutel-waardeparen, controleert de aanwezigheid, volgt de invoegvolgorde en zet verzamelingen om in arrays of objecten wanneer een andere bewerking die structuur nodig heeft. Gelijkheid blijft van belang: twee records met overeenkomende velden kunnen in beide verzamelingen twee afzonderlijke waarden blijven.

4.1 Sla sleutel-waardeparen op in een Map

Een Map slaat koppelingen tussen sleutels en waarden op. Anders dan de stringsleutels van een gewoon object kan een sleutel in een Map een getal, een object of een andere waarde zijn zonder in een string te worden omgezet.

Maak en beheer sleutel-waardeparen
const stock = new Map();
stock.set("apples", 12).set("pears", 7);
stock.get("apples"); // 12
stock.has("kiwis");  // false
stock.size;           // 2

set voegt een sleutel-waardepaar toe of vervangt de waarde ervan en geeft de Map terug om aanroepen aaneen te schakelen. get geeft undefined terug voor een ontbrekende sleutel; gebruik has om dat te onderscheiden van een sleutel-waardepaar waarin undefined is opgeslagen. delete(key) geeft terug of een sleutel-waardepaar is verwijderd en clear() maakt de verzameling leeg.

Blokhaaknotatie gebruikt een andere opslagplaats: stock["plums"] = 5; voegt een gewone eigenschap toe aan het Map-object. Er wordt geen sleutel-waardepaar aangemaakt dat zichtbaar is voor get, has of size. Gebruik de Map-methoden voor sleutel-waardeparen.

Behoud sleuteltypen en identiteit

m.set(1, "number"); m.set("1", "text"); maakt twee sleutel-waardeparen aan. In een gewoon object zouden de sleutels 1 en "1" naar één eigenschap verwijzen. Map-sleutels worden vergeleken zoals met ===, behalve dat NaN gelijk is aan zichzelf en positieve en negatieve nul dezelfde sleutel delen.

const person = { id: 1 };
const notes = new Map([[person, "ready"]]);
notes.get(person);      // "ready"
notes.get({ id: 1 });   // undefined

Bij de tweede opzoekactie wordt een nieuw object gemaakt. Overeenkomende velden maken dat niet tot dezelfde sleutel. Bewaar en hergebruik de oorspronkelijke objectreferentie wanneer je een object als sleutel gebruikt.

Doorloop en converteer paren
for (const [name, count] of stock) {
  console.log(name, count);
}

Een Map levert [key, value]-paren in de volgorde waarin de sleutels voor het eerst zijn toegevoegd. Als je een waarde vervangt, verplaatst de sleutel niet. keys(), values() en entries() geven itereerbare weergaven terug die je met een lus kunt doorlopen of met spreadsyntaxis in arrays kunt opnemen. forEach geeft aan zijn callback eerst de waarde en dan de sleutel door.

new Map(Object.entries(obj)) zet de sleutel-waardeparen van een record om in een Map. Object.fromEntries(map) maakt een object; gebruik dit wanneer sleutels strings zijn, omdat objectsleutels niet elk type Map-sleutel kunnen behouden. [...map] maakt een array van paren, handig om de sleutel-waardeparen van een Map als JSON op te slaan.

Tel wisselende sleutels
const words = "the cat saw the dog and the bird".split(" ");
const counts = new Map();
for (const word of words) {
  counts.set(word, (counts.get(word) ?? 0) + 1);
}

De eerste keer begint de telling bij nul en wordt er één opgeteld. Bij latere voorkomens wordt de opgeslagen telling gelezen en verhoogd. counts.get("the") is 3 en counts.size is 6: de grootte telt verschillende woorden, niet alle acht voorkomens.

Kies een gewoon object voor een record met bekende velden, vooral voor gegevens die geschikt zijn voor JSON. Kies een Map voor wisselende sleutels, frequente controles van de grootte of sleutels waarvan het type behouden moet blijven. De nieuwere methode Map.groupBy behoudt de typen groepssleutels:

const owner = { name: "Ari" };
const jobs = [{ owner, done: false }, { owner, done: true }];
const byOwner = Map.groupBy(jobs, job => job.owner);
byOwner.get(owner).length; // 2

Doorloop in oudere code de taken. Gebruik voor elke eigenaar has en set om eenmaal een groepsarray te maken en voeg daarna het record toe met get(owner).push(job). Door de eigenaar als objectsleutel te bewaren, onderscheid je verschillende eigenaars, ook als hun naamvelden overeenkomen. Een WeakMap kan metagegevens aan objecten koppelen zonder sleutelobjecten die verder onbereikbaar zijn in leven te houden. Een WeakMap heeft geen iteratie of grootte. Moderne WeakMaps accepteren ook niet-geregistreerde symbolen als sleutels.

Belangrijkste punten

  • Map-sleutels behouden hun type en vergelijken objecten op identiteit.
  • Gebruik set, get, has en delete voor sleutel-waardeparen, geen blokhaaknotatie.
  • size telt sleutel-waardeparen en iteratie volgt de invoegvolgorde van sleutels.
  • Maps worden geconverteerd via sleutel-waardeparen.
  • Een WeakMap kan metagegevens van objecten bewaren zonder sleutelobjecten in leven te houden.
  • Map.groupBy behoudt de typen groepssleutels in een nieuwere groeperings-API.

4.2 Bewaar unieke waarden in een Set

Een Set slaat unieke waarden op. De belangrijkste vragen zijn of een waarde aanwezig is en hoe twee verzamelingen overlappen.

Voeg waarden toe en controleer ze
const tags = new Set(["js", "css", "js"]);
tags.size;       // 2
tags.add("html");
tags.has("css"); // true

Een bestaande waarde toevoegen verandert niets. add geeft de Set terug om aanroepen aaneen te schakelen. delete(value) geeft terug of de waarde is verwijderd, terwijl clear() alle waarden verwijdert. De constructor ontvangt één itereerbare waarde: gebruik new Set([1, 2, 3]). new Set(1, 2, 3) werpt een TypeError op omdat de eerste invoer niet itereerbaar is. Een string is itereerbaar, dus bevat new Set("hello") de waarden "h", "e", "l" en "o".

Een Set heeft geen posities met indexen. tags[0] is undefined. Doorloop de Set met for...of, roep forEach aan of converteer naar een array voor bewerkingen zoals map en filter. Iteratie volgt de invoegvolgorde; als je een waarde verwijdert en opnieuw toevoegt, komt die achteraan te staan.

Verwijder dubbele waarden zonder te sorteren
const unique = [...new Set([3, 1, 3, 2, 1])];
// [3, 1, 2]

De Set behoudt het eerste voorkomen van elke waarde. Met spreadsyntaxis komen die waarden in een array terecht. Array.from(set) voert dezelfde conversie uit.

Waarden worden vergeleken zoals met ===, behalve dat NaN gelijk is aan zichzelf; positieve en negatieve nul tellen als één waarde. Objectwaarden worden op identiteit vergeleken: new Set([{ id: 1 }, { id: 1 }]).size is 2. Om één record per ID te bewaren, bouw je een Map met die ID als sleutel en lees je vervolgens de waarden. Latere records met dezelfde ID vervangen eerdere records, omdat set een bestaand sleutel-waardepaar bijwerkt.

Voor herhaalde aanwezigheidscontroles in grote verzamelingen voorkomt een Set dat includes een array één voor één moet doorzoeken. Gebruik een Set wanneer aanwezigheid belangrijker is dan positie.

Vergelijk twee verzamelingen

Nieuwere Set-methoden zijn vanaf 2024 beschikbaar in de grote browsers. Met a met de waarden 1, 2, 3, 4 en b met de waarden 3, 4, 5:

BewerkingBetekenisResulterende waarden
a.union(b)In minstens één verzameling1, 2, 3, 4, 5
a.intersection(b)In beide3, 4
a.difference(b)In a maar niet in b1, 2
a.symmetricDifference(b)In precies één1, 2, 5

Deze methoden geven nieuwe Sets terug. isSubsetOf controleert of elke waarde in de andere verzameling zit. isSupersetOf controleert de omgekeerde insluiting. isDisjointFrom controleert of de verzamelingen geen waarden delen. Alle drie geven booleaanse waarden terug. Zo is new Set([3, 4]).isSubsetOf(a) waar. Verschil heeft een richting: waarden in b maar niet in a zouden alleen 5 zijn.

In een oudere omgeving kun je een doorsnede schrijven als new Set([...a].filter(x => b.has(x))).

Het gewone JSON.stringify(set) levert "{}" op, waarbij de opgeslagen waarden verloren gaan. Converteer naar een array voordat je JSON schrijft en gebruik vervolgens new Set(parsedArray) bij het lezen. Een WeakSet kan objecten als verwerkt markeren zonder verder onbereikbare objecten in leven te houden. Een WeakSet kan niet worden doorlopen. Moderne WeakSets accepteren ook niet-geregistreerde symbolen.

Belangrijkste punten

  • Een Set bewaart elke verschillende waarde één keer en controleert aanwezigheid met has.
  • Converteer een Set naar een array om indexen of arraymethoden te gebruiken.
  • Objectwaarden blijven verschillend tenzij hun referenties overeenkomen.
  • Vereniging, doorsnede, verschil en symmetrisch verschil beantwoorden verschillende vragen over aanwezigheid.
  • Het verschil hangt af van welke Set eerst komt.
  • Converteer Set-waarden naar een array voordat je JSON schrijft.
  • Een WeakSet kan objecten markeren zonder ze in leven te houden.
5

Converteer gegevens naar JSON en terug

JSON draagt gestructureerde gegevens over als tekst. Converteren tussen die tekst en actieve JavaScript-waarden is alleen nuttig als je weet welke informatie de conversie overleeft. Je herkent geldige JSON, bepaalt hoe waarden worden geschreven en handelt ongeldige invoer af bij het lezen. Na succesvol ontleden is ook een structuurcontrole nodig voordat het programma op de velden vertrouwt; geldige tekst alleen garandeert niet dat de gegevens aan de verwachtingen voldoen.

5.1 Lees en schrijf het JSON-formaat

JSON, een afkorting van JavaScript Object Notation, is een taalonafhankelijk tekstformaat voor gestructureerde gegevens. Een object is een actieve JavaScript-waarde; JSON is tekst die zo'n waarde kan beschrijven.

Herken de zes soorten waarden

JSON ondersteunt objecten, arrays, strings, getallen, booleaanse waarden en null. Elk daarvan kan de waarde op het hoogste niveau zijn. De tekst 42 is geldige JSON, ook zonder accolades. JSON heeft geen weergave voor functies, undefined, datums als afzonderlijk type, Map, Set, NaN of Infinity.

{
  "name": "Amara",
  "age": 34,
  "languages": ["en", "yo"],
  "address": null,
  "member": true
}

Dezelfde structurele ideeën komen voor in JavaScript-literals, maar de toegestane schrijfwijze is strikter. JSON wordt gebruikt in configuraties en voor gegevensuitwisseling. Uitgewisselde JSON gebruikt UTF-8-codering en het mediatype application/json; JSON-bestanden gebruiken de extensie .json.

Pas de syntaxisregels toe

Elke objectsleutel moet een string tussen dubbele aanhalingstekens zijn. Strings vereisen ook dubbele aanhalingstekens. Komma's scheiden eigenschappen of arrayitems, maar na het laatste item mag geen komma staan. Commentaar is verboden. Witruimte tussen waarden en leestekens is toegestaan.

TekstWaarom die ongeldig is
{name: "Amara"}De sleutel mist dubbele aanhalingstekens.
{'name': 'Amara'}Enkele aanhalingstekens begrenzen geen JSON-strings.
{"a": 1,}Na de laatste komma volgt geen eigenschap.
{"a": undefined}Undefined is geen JSON-waarde.

Getallen gebruiken decimale notatie. 1.5e3, -0.25 en 0 zijn geldig. 07, +1 en 0x1F zijn ongeldig omdat JSON voorloopnullen, een plusteken aan het begin en hexadecimale notatie verbiedt.

Gebruik escapesequenties voor tekens in strings

Gebruik \" voor een dubbel aanhalingsteken, \\ voor een backslash, \n voor een nieuwe regel en \t voor een tab binnen een JSON-string. Een letterlijk regeleinde mag niet binnen een JSON-string voorkomen. Laat JSON.stringify escapesequenties genereren uit werkelijke stringwaarden, zodat aanhalingstekens in de tekst de uitvoer niet ongeldig kunnen maken.

Een Unicode-escapesequentie bestaat uit een backslash, de letter u en vier hexadecimale cijfers voor één UTF-16-code-eenheid. Zo staat \u00e9 voor é. Een teken buiten dat bereik kan twee van zulke escapesequenties nodig hebben; het kan ook rechtstreeks in de string worden geschreven. De aanhalingstekens rond JSON-tekst in JavaScript-broncode vormen een afzonderlijke laag ten opzichte van de aanhalingstekens binnen de JSON zelf.

Behoud identifiers en voorkom dubbele sleutels

JavaScript-getallen behouden elk geheel getal in het veilige bereik van -9.007.199.254.740.991 tot en met 9.007.199.254.740.991. Buiten dat bereik blijven sommige gehele getallen exact en worden andere afgerond. Het ontleden van '{"id":9007199254740993}' geeft een id-waarde van 9007199254740992. Sla lange identifiers op als JSON-strings wanneer de exacte cijfers van belang zijn.

Objectsleutels moeten binnen elk JSON-object uniek zijn. De JavaScript-functie JSON.parse bewaart het laatste voorkomen als een sleutel wordt herhaald: het ontleden van '{"a":1,"a":2}' levert { a: 2 } op. Afzonderlijke eigenschappen zijn niet uit die herhaalde naam te herstellen.

Belangrijkste punten

  • JSON is tekst met zes soorten waarden, waaronder primitieve waarden op het hoogste niveau.
  • Sleutels en strings hebben dubbele aanhalingstekens nodig; commentaar en komma's aan het einde zijn ongeldig.
  • JSON-getallen staan geen hexadecimale notatie, plustekens aan het begin of voorloopnullen toe.
  • Escapesequenties geven speciale tekens binnen strings weer.
  • Gebruik strings voor lange identifiers waarvan de exacte cijfers behouden moeten blijven.
  • Herhaalde objectsleutels zijn onveilig; JSON.parse bewaart de laatste waarde.

5.2 Zet waarden om in JSON-tekst met JSON.stringify

JSON.stringify converteert ondersteunde JavaScript-waarden naar JSON-tekst. Bepaal wat de tekst moet behouden voordat je een record met methoden of verzamelingswaarden converteert.

Schrijf compacte of ingesprongen tekst
const person = { name: "Amara", age: 34, tags: ["admin"] };
const text = JSON.stringify(person);
// '{"name":"Amara","age":34,"tags":["admin"]}'

Het resultaat is een string, dus is typeof text gelijk aan "string". Eigen opsombare eigenschappen met strings als sleutels worden geschreven in de volgorde van Object.keys. JSON.stringify(person, null, 2) voegt regeleinden en twee spaties inspringing per niveau toe. Het tweede argument is null omdat er geen vervangingsargument wordt gebruikt. Numerieke inspringing is begrensd op 10 spaties; van een string voor inspringing worden hoogstens de eerste 10 tekens gebruikt.

Voorspel welke waarden wegvallen en veranderen
const data = {
  a: undefined,
  b: () => 1,
  c: NaN,
  d: [undefined, Infinity]
};
JSON.stringify(data); // '{"c":null,"d":[null,null]}'

Een objecteigenschap met undefined, een functie of een symbool wordt weggelaten. In een array wordt zo'n waarde null, zodat die positie behouden blijft. NaN en Infinity worden op beide plaatsen null. Op het hoogste niveau zorgen niet-ondersteunde waarden zoals undefined of een functie ervoor dat stringify de waarde undefined teruggeeft, geen JSON-tekst.

Een Date schrijft via toJSON zijn ISO-string in UTC. Gewone items van Map en Set worden niet geschreven, dus wordt elk van beide verzamelingen {}. Converteer Set-waarden naar een array en Map-items naar paren of een object met stringsleutels voordat je ze schrijft.

Een circulaire referentie en een gewone BigInt zoals 10n veroorzaken een TypeError. Gedeelde referenties die geen cyclus vormen, kunnen worden geserialiseerd, maar JSON behoudt hun gedeelde identiteit niet.

Kies gegevens met een vervangingsargument
const user = { name: "Rae", email: "rae@example.com", password: "x9!k", age: 31 };
JSON.stringify(user, ["name", "email"]);
// '{"name":"Rae","email":"rae@example.com"}'

Een array als vervangingsargument selecteert eigenschapsnamen. Een functie als vervangingsargument transformeert waarden wanneer ze worden bezocht, te beginnen met de hele invoer onder de sleutel "":

JSON.stringify(user, (key, value) =>
  key === "password" ? undefined : value
);

Als de functie undefined teruggeeft, wordt een objecteigenschap weggelaten, wordt een arraypositie null of is het totale resultaat undefined wanneer de functie dit voor de hoofdwaarde teruggeeft. Geef voor gegevens die je wilt behouden de ongewijzigde waarde terug.

De methode toJSON() van een object kan de weergave ervan kiezen. Voor { celsius: 21, toJSON() { return { c: this.celsius }; } } schrijft omzetting naar een string '{"c":21}'.

Bouw JSON niet zelf op door strings tussen aanhalingstekens samen te voegen: aanhalingstekens of regeleinden in de inhoud kunnen de syntaxis ongeldig maken. Zet ook niet al geserialiseerde tekst om in een string met de verwachting een objectweergave te krijgen. Als je '{"a":1}' omzet in een JSON-string, wordt een string gecodeerd; als je dat resultaat één keer ontleedt, krijg je een string terug en geen object.

Belangrijkste punten

  • JSON.stringify geeft meestal JSON-tekst terug; niet-ondersteunde waarden op het hoogste niveau kunnen undefined opleveren.
  • Niet-ondersteunde objecteigenschappen verdwijnen, terwijl niet-ondersteunde arrayitems null worden.
  • Datums worden strings; Map en Set hebben expliciete conversie nodig.
  • Circulaire structuren en gewone BigInts werpen een TypeError op.
  • Vervangingsargumenten en toJSON bepalen de geschreven weergave.
  • JSON-tekst opnieuw omzetten met stringify codeert een string, niet het object in die tekst.

5.3 Zet JSON-tekst om in waarden met JSON.parse

JSON.parse leest JSON-tekst en geeft de waarde terug die de tekst beschrijft. Ontleden controleert de syntaxis van de tekst; controleren of het resultaat bij je programma past, is een afzonderlijke taak.

Lees de waarde en bekijk daarna de velden
const data = JSON.parse('{"city":"Lima","tempC":19.5}');
data.tempC + 1; // 20.5

De buitenste enkele aanhalingstekens begrenzen een JavaScript-string. De dubbele aanhalingstekens daarin horen bij JSON. Ontleden maakt een gewoon object met een numerieke eigenschap tempC. Tekst die een array beschrijft, levert een array op; primitieve JSON-teksten leveren de bijbehorende primitieve waarden op.

Gegevens die al een object zijn, hoef je niet te ontleden. JSON.parse({ a: 1 }) zet dat argument eerst om in "[object Object]" en werpt dan een SyntaxError op. JSON.parse(undefined) mislukt ook omdat "undefined" geen geldige JSON-tekst is.

Handel ongeldige tekst af
function safeParse(text, fallback) {
  try {
    return JSON.parse(text);
  } catch (error) {
    return fallback;
  }
}
safeParse("{ok:true}", null); // null

Ongeldige invoer, waaronder een lege string, JSON-strings met enkele aanhalingstekens, sleutels zonder aanhalingstekens en komma's aan het einde, werpt een SyntaxError op. Door die fout op te vangen, geef je het programma een bewuste terugvaloptie in plaats van het te stoppen. Een succesvol ontlede null is ook mogelijk, dus kies hoe de aanroeper een terugvalwaarde van geldige gegevens kan onderscheiden als dat verschil van belang is.

Herstel geselecteerde waarden met een herstelcallback

Een datum die als tekst is opgeslagen, komt terug als string. Een array van sleutel-waardeparen blijft een array totdat new Map(pairs) die omzet in een Map. Functies die bij het schrijven zijn weggelaten, kunnen niet uit de resterende tekst worden hersteld.

const text = '{"title":"Dentist","due":"2026-03-01T09:00:00.000Z"}';
const event = JSON.parse(text, (key, value) =>
  key === "due" ? new Date(value) : value
);

De herstelcallback bezoekt binnenste waarden vóór hun containers en eindigt met het hele resultaat onder sleutel "". Een teruggegeven waarde vervangt de huidige waarde. Als de callback undefined teruggeeft, wordt die eigenschap verwijderd; als de callback dit voor de hoofdwaarde teruggeeft, wordt het hele ontleedresultaat undefined. Als je voor andere sleutels return value vergeet, kun je dus de gegevens wissen die je wilde behouden.

Controleer de structuur en plan een heen-en-terugconversie

Geldige JSON kan nog steeds de verkeerde typen bevatten. Het ontleden van '{"temp":"19"}' laat een string over, dus zou data.temp + 1 samenvoegen tot "191". Controleer verplichte velden en typen, bijvoorbeeld met typeof data?.temp === "number", voordat je gaat rekenen. Converteer alleen met Number wanneer het bedoelde formaat een numerieke string toestaat; optionele ketenvorming en ?? kunnen velden opvangen die mogen ontbreken.

Voor const settings = { theme: "dark", volume: 0.8, recent: ["a.txt"] }; levert omzetting naar een string 48 tekens JSON-tekst op. Ontleden herstelt dezelfde veldgegevens, maar loaded === settings is onwaar omdat ontleden nieuwe objecten maakt. Een Date komt terug als string, een objecteigenschap met undefined verdwijnt en een niet-geconverteerde Set komt terug als {}. Converteer speciale waarden vóór het schrijven en herstel hun bedoelde typen na het lezen.

Belangrijkste punten

  • JSON.parse leest tekst en werpt een SyntaxError op bij ongeldige JSON.
  • Succesvol ontleden controleert niet de verplichte velden of hun typen.
  • Een herstelcallback bezoekt eerst de onderliggende waarden en moet de waarden teruggeven die je wilt behouden.
  • Heen-en-terugconversies via JSON maken nieuwe objecten en behouden alleen gegevens die JSON kan weergeven.
  • Herstel verzamelings- en datumtypen expliciet na het ontleden.

JavaScript-objecten en JSON: voorbeelden

5 Walkthroughs

1

Volg een verzendrecord

16 stappen
Maak, bekijk en kopieer een genest record terwijl je volgt welke waarden worden gedeeld.
  1. 1
    IntroductieBouw een record dat je kunt bekijken

    Een zending combineert een ID, een bestemming en pakketrecords. Je bouwt de zending op, bekijkt de velden en volgt gedeelde en gekopieerde gegevens. Twee namen kunnen één referentie naar hetzelfde record bevatten en een oppervlakkige kopie deelt nog steeds geneste niveaus, zodat een bijwerking gegevens kan bereiken die je gescheiden wilde houden.

    De voorbeelden met de zending lopen door over de dia's, tenzij een stap expliciet een afzonderlijk object maakt.

  2. 2
    VoorbeeldMaak de zending
    const shipment = {
      id: "s12",
      destination: "Porto",
      delayMin: 0
    };
    

    De literal maakt drie eigenschappen aan. Vertraging wordt gemeten in minuten, waarbij nul een geldige waarde is. shipment.destination leest "Porto". Const staat toe dat eigenschappen worden bijgewerkt.

  3. 3
    VoorbeeldKies een veld terwijl het programma draait
    const field = "destination";
    shipment[field] = "Braga";
    shipment.checked = true;
    

    Blokhaaknotatie evalueert field en werkt de eigenschap destination bij. De toewijzing voegt ook checked toe omdat die eigenschap nog niet bestond. De zending heeft nog steeds dezelfde identiteit; geen van beide bewerkingen vervangt het buitenste object. Als je shipment.field zou schrijven, zou je in plaats daarvan een afzonderlijke eigenschap aanmaken die letterlijk "field" heet.

  4. 4
    UitdagingLees een berekende naam

    Wat leest shipment[field] nu en heeft de zending een eigen eigenschap field?

    ---reveal---

    De expressie leest "Braga". De variabele field bevat de sleutel "destination", dus zowel de bijwerking als de leesbewerking bereikt die eigenschap. Object.hasOwn(shipment, "field") is onwaar omdat er geen letterlijke eigenschap field is aangemaakt. Een variabele waarmee je een eigenschap kiest, wordt zelf geen onderdeel van het record.

  5. 5
    UitlegControleer nul zonder die te verliezen

    shipment.delayMin is nul, dus slaat een voorwaarde die controleert of de waarde truthy is haar instructies over. De eigenschap bestaat nog steeds.

    Object.hasOwn(shipment, "delayMin") geeft waar terug. Gebruik een controle op eigen eigenschappen voor opgeslagen velden; de operator in neemt ook overgeërfde eigenschappen mee.

  6. 6
    VoorbeeldLees de sleutel-waardeparen
    const pairs = Object.entries(shipment);
    const count = Object.keys(shipment).length;
    

    Er zijn nu vier eigen opsombare velden met strings als sleutels, waaronder checked. Entries geeft voor elk veld één [key, value]-paar. Je kunt ze met for (const [key, value] of pairs) doorlopen om beide onderdelen te bekijken. Een directe for...of-lus over het gewone object shipment zou een fout opwerpen omdat dat object niet itereerbaar is.

  7. 7
    UitdagingOnderscheid bestaan van waarde

    Stel dat shipment.note = undefined; wordt toegevoegd. Wat geven shipment.note en Object.hasOwn(shipment, "note") terug?

    ---reveal---

    Ze geven undefined en true terug. De toewijzing maakt de eigenschap aan, ook al is de waarde undefined. Als je de eigenschap verwijdert, verandert het resultaat van de aanwezigheidscontrole in false, terwijl een latere leesbewerking nog steeds undefined oplevert. De waarde alleen kan deze twee situaties niet onderscheiden.

  8. 8
    AnalogieVolg twee routes naar één record

    Een referentie werkt als een route naar een record: als je de route kopieert, krijg je een andere manier om dezelfde bestemming te bereiken. Er wordt geen tweede record opgebouwd.

    const alias = shipment;
    alias.checked = false;
    

    shipment.checked is nu ook false. Beide variabelenamen bereiken één object, dus is alias === shipment true. Overeenkomende referenties verklaren de gedeelde bijwerking; er is geen synchronisatiestap tussen twee kopieën uitgevoerd.

  9. 9
    VoorbeeldVoeg gegevens toe die een oppervlakkige kopie zal delen
    shipment.packages = [{ massG: 450 }, { massG: 700 }];
    const shallow = { ...shipment };
    shallow.destination = "Faro";
    shallow.packages[0].massG = 500;
    

    Het nieuwe buitenste record heeft een eigen bestemming, dus blijft shipment.destination Braga. De waarde van packages is dezelfde arrayreferentie als voorheen. Als je dat gedeelde pad volgt, verandert ook de massa van het eerste pakket in de oorspronkelijke zending in 500.

  10. 10
    VoorbeeldMaak een ondersteunde diepe kopie
    const deep = structuredClone(shipment);
    deep.packages[0].massG = 600;
    

    Het eerste oorspronkelijke pakket blijft op 500 g omdat de diepe kopie een eigen geneste array en eigen pakketobjecten heeft. Dit record bevat alleen ondersteunde gegevens. Als het een eigenschap met een functie als waarde zou bevatten, zou structuredClone een DataCloneError opwerpen in plaats van die methode ongemerkt weg te laten.

  11. 11
    UitdagingVoorspel de grens van bevriezen

    Voer deze instructies uit. Werpt de geneste toewijzing een fout op en wat is daarna de tweede massa?

    Object.freeze(shipment);
    shipment.packages[1].massG = 750;
    

    ---reveal---

    De toewijzing slaagt en stelt de massa in op 750. Het bevriezen van shipment beschermt de eigen eigenschappen, maar niet de array waarnaar wordt verwezen of de records daarin. Een hertoewijzing van shipment.destination zou in strikte modus een TypeError opwerpen; deze geneste toewijzing bereikt een ander, niet-bevroren object.

  12. 12
    VoorbeeldBereken het huidige totaal
    const totalG = shipment.packages.reduce(
      (sum, pack) => sum + pack.massG, 0
    );
    

    Na de vorige bijwerkingen bevat de oorspronkelijke zending massa's van 500 en 750 g. Reduce begint bij nul, telt er 500 en daarna 750 bij op, wat 1.250 oplevert. Het totaal wordt berekend uit de huidige pakketten. Als hun massa's later veranderen, voer je de berekening opnieuw uit; dit opgeslagen getal wordt niet vanzelf opnieuw berekend.

  13. 13
    TipVang een optioneel pad op
    const contactName = shipment.contact?.name ?? "Unassigned";
    

    Er is geen eigenschap contact in het record, dus levert optionele ketenvorming undefined op en geeft de terugvaloptie "Unassigned". Dit pad mag ontbreken. Houd verplichte velden zichtbaar voor validatie in plaats van alle fouten ongemerkt met standaardwaarden op te vangen. De terugval bij null of undefined behoudt ook een bewust lege naam, anders dan een terugval met logische OF.

  14. 14
    UitdagingBehoud een geldige nul

    Wat geven shipment.delayMin ?? 10 en shipment.delayMin || 10 terug?

    ---reveal---

    De eerste geeft 0 terug; de tweede geeft 10 terug. Terugval bij null of undefined vervangt alleen null of undefined, terwijl logische OF elke falsy-waarde vervangt. Voor deze zending is een vertraging van nul minuten geregistreerd, dus als je die als ontbrekend behandelt, voeg je een vertraging toe die de opgeslagen gegevens nooit hebben vermeld.

  15. 15
    UitdagingCombineer een kopie met een optionele bijwerking

    Er wordt een nieuw record gemaakt met const next = { ...shipment };, gevolgd door next.packages[0].massG = 520;. Wat gebeurt er met de eerste massa van shipment en is next hetzelfde buitenste object?

    ---reveal---

    De oorspronkelijke massa wordt 520 omdat de geneste array wordt gedeeld. next === shipment is false omdat spreadsyntaxis een nieuw buitenste object heeft gemaakt. Als je het buitenste record kopieert, staan toewijzingen aan de eigen eigenschappen los van elkaar, maar wordt niet een heel genest pad onafhankelijk.

  16. 16
    SamenvattingKies de controle voor de taak

    Kies een eigenschap met een letterlijke of berekende sleutel en onderscheid bestaan van de vraag of een waarde truthy is. Volg vóór een bijwerking of het pad gedeelde gegevens bereikt.

    Kopieer geneste niveaus die onafhankelijk moeten zijn. Bereken afgeleide totalen opnieuw nadat hun invoer verandert.

2

Houd een actie verbonden met haar object

12 stappen
Volg methodeaanroepen, vastgelegde context en callbacks met een kleine teller.

Sla deze les op om elke Walkthrough stap voor stap te volgen.

  1. 1
    IntroductieVolg een actie terwijl die wordt doorgegeven
  2. 2
    VoorbeeldMaak een actie en roep die aan
  3. 3
    UitdagingLees de actie zonder die uit te voeren
  4. 4
    VoorbeeldLeen de gewone functie
  5. 5
    UitdagingKoppel de geleende methode los
  6. 6
    KernpuntZet een pijlfunctie binnen de methode
  7. 7
    VoorbeeldOmhul de benodigde aanroep
  8. 8
    VoorbeeldBind een callback één keer
  9. 9
    UitdagingKies directe of latere uitvoering
  10. 10
    TipGeef een bestaande binding voorrang
  11. 11
    UitdagingVolg een gebonden methode via een ander object
  12. 12
    SamenvattingLees de aanroepvorm
3

Pak opties uit en bouw een bijgewerkt record

14 stappen
Lees patronen van buiten naar binnen en kopieer daarna alleen de niveaus die moeten veranderen.

Sla deze les op om elke Walkthrough stap voor stap te volgen.

  1. 1
    IntroductieLees compacte syntaxis in kleine stappen
  2. 2
    VoorbeeldSelecteer en hernoem velden
  3. 3
    VoorbeeldGa een genest patroon binnen
  4. 4
    UitdagingLees een hernoemd genest veld
  5. 5
    UitdagingOnderscheid null van een ontbrekende waarde
  6. 6
    VoorbeeldPak een teruggegeven bereik uit
  7. 7
    VoorbeeldVerzamel de rest in een eigen array
  8. 8
    UitdagingVerwissel waarden voordat je ze gebruikt
  9. 9
    VoorbeeldVoeg standaardwaarden en vervangende waarden samen
  10. 10
    VoorbeeldKopieer het geneste niveau dat verandert
  11. 11
    VerbandLaat een veld weg uit het nieuwe record
  12. 12
    UitdagingKies een onafhankelijke bijwerking
  13. 13
    UitdagingVerbind patronen voor sleutel-waardeparen met spreadsyntaxis
  14. 14
    SamenvattingBepaal de taak voordat je waarden volgt
4

Volg tellingen en unieke aanwezigheid

11 stappen
Gebruik Map voor veranderende waarden met sleutels en Set voor aanwezigheid en vergelijk daarna verzamelingen.

Sla deze les op om elke Walkthrough stap voor stap te volgen.

  1. 1
    IntroductieKies wat de verzameling moet onthouden
  2. 2
    VoorbeeldMaak tellingen met Map-methoden
  3. 3
    TipHoud sleutel-waardeparen gescheiden van eigenschappen
  4. 4
    UitdagingHoud sleuteltypen verschillend
  5. 5
    VoorbeeldHergebruik een objectsleutel
  6. 6
    VoorbeeldVerzamel unieke labels
  7. 7
    UitdagingBepaal of records dubbel zijn
  8. 8
    VoorbeeldZoek de gedeelde en ontbrekende labels
  9. 9
    KernpuntStel een andere vraag over aanwezigheid
  10. 10
    UitdagingVerbind tellingen met aanwezigheid
  11. 11
    SamenvattingStem de structuur af op de bewerking
5

Schrijf, lees en controleer JSON-gegevens

14 stappen
Plan een weergave die geschikt is voor JSON, handel ongeldige tekst af en herstel de bedoelde typen.

Sla deze les op om elke Walkthrough stap voor stap te volgen.

  1. 1
    IntroductiePlan beide richtingen van de conversie
  2. 2
    UitlegLees tekst als tekst
  3. 3
    UitdagingLos een syntaxisprobleem op
  4. 4
    VoorbeeldBekijk de actieve instellingen
  5. 5
    VoorbeeldConverteer de verzameling vóór het schrijven
  6. 6
    TipLaat de serialisatiefunctie escapesequenties in strings aanbrengen
  7. 7
    UitdagingVoorspel wat er met een niet-ondersteund arrayitem gebeurt
  8. 8
    VoorbeeldOntleed en herstel de aanwezigheidscontrole
  9. 9
    VoorbeeldHandel ongeldige tekst bewust af
  10. 10
    UitdagingControleer een geldige maar ongeschikte waarde
  11. 11
    UitlegHerstel één veld met een herstelcallback
  12. 12
    UitdagingBehoud het onderscheid tussen Map-sleutels
  13. 13
    VerbandHoud klonen en uitwisselen gescheiden
  14. 14
    SamenvattingControleer syntaxis, structuur en weergave

JavaScript-objecten en JSON: oefenvragen

50 Oefenvragen in 5 sets

Set 1: Lees records en volg waarden10 Oefenvragen

Vraag 1 van 10

Wat geeft sensor[field] terug?

const sensor = { tempC: 16, field: "room" };
const field = "tempC";
  1. "room"
  2. 16
  3. "tempC"
  4. undefined
Toon antwoordVerberg antwoord
Antwoord: B
Blokhaaknotatie gebruikt de waarde van field, "tempC", om de eigenschap met waarde 16 te selecteren. Puntnotatie in sensor.field zou daarentegen de letterlijke eigenschap field lezen en "room" teruggeven.

Vraag 2 van 10

Wat geeft Object.hasOwn(record, "enabled") terug?

const record = { enabled: false };
  1. false
  2. undefined
  3. null
  4. true
Toon antwoordVerberg antwoord
Antwoord: D
Enabled is een eigen eigenschap van het record, dus is het resultaat van de controle true. De opgeslagen waarde false zou niet slagen voor een controle of de waarde truthy is, maar die waarde maakt de eigenschap niet afwezig.

Vraag 3 van 10

Wat zijn record.region en record.key?

const key = "region";
const record = { [key]: "east" };
record[key] = "west";
  1. "west" en undefined
  2. "east" en "west"
  3. undefined en "west"
  4. "west" en "east"
Toon antwoordVerberg antwoord
Antwoord: A
De berekende sleutel maakt region aan en de toewijzing met blokhaken werkt de waarde bij naar "west". Er wordt geen letterlijke eigenschap key aangemaakt, dus geeft het lezen van record.key undefined terug.

Vraag 4 van 10

Wat is meter.value na deze aanroep?

const meter = {
  value: 7,
  add() { this.value += 3; }
};
meter.add();
  1. 7
  2. 3
  3. 10
  4. undefined
Toon antwoordVerberg antwoord
Antwoord: C
Door de methodeaanroep wordt meter het ontvangende object en verandert value van 7 in 10. Dat een methode zonder return undefined teruggeeft, maakt de bijwerking van de eigenschap niet ongedaan.

Vraag 5 van 10

Wat geeft right.read() terug?

const left = { name: "Ivo", read() { return this.name; } };
const right = { name: "Nia", read: left.read };
  1. "Ivo"
  2. "Nia"
  3. undefined
  4. Een TypeError
Toon antwoordVerberg antwoord
Antwoord: B
De gewone functie wordt via right aangeroepen, dus is this gelijk aan right en is de teruggegeven naam "Nia". De functie is oorspronkelijk in left geschreven, maar die plaats bindt het ontvangende object niet. Als de functie "Ivo" zou teruggeven, zou de oorspronkelijke opslagplaats worden verward met het object dat bij de huidige aanroep wordt gebruikt.

Vraag 6 van 10

Wat zijn title en score na destructurering?

const { name: title, score = 8 } = { name: "Reef", score: null };
  1. "Reef" en null
  2. "Reef" en 8
  3. undefined en 8
  4. undefined en null
Toon antwoordVerberg antwoord
Antwoord: A
Het patroon leest de eigenschap name in de lokale variabele title. De standaardwaarde voor score wordt alleen gebruikt bij undefined, dus blijft de expliciete null behouden. Als je null door 8 zou vervangen, zou je de ruimere regel voor terugval bij null of undefined toepassen op destructurering, die alleen bij undefined een standaardwaarde gebruikt.

Vraag 7 van 10

Welke waarde krijgt third?

const [, , third] = [4, 9, 12, 18];
  1. 4
  2. 9
  3. 12
  4. 18
Toon antwoordVerberg antwoord
Antwoord: C
De twee lege plaatsen slaan 4 en 9 over, zodat 12 overblijft voor third. Als je 9 zou kiezen, zou je maar één positie overslaan; de variabelenaam zelf selecteert geen index.

Vraag 8 van 10

Wat zijn m.size en m.get(2)?

const m = new Map([[2, "number"], ["2", "text"]]);
  1. 1 en "text"
  2. 2 en "text"
  3. 1 en "number"
  4. 2 en "number"
Toon antwoordVerberg antwoord
Antwoord: D
Een Map behoudt sleuteltypen, dus nemen het getal 2 en de string "2" twee afzonderlijke sleutel-waardeparen in. Het opzoeken van het getal 2 geeft "number" terug. Een grootte van 1 zou ontstaan als beide sleutels als dezelfde string werden behandeld, zoals deze namen zich gedragen als gewone objecteigenschappen.

Vraag 9 van 10

Een gegevensbestand moet de exacte ID-cijfers 9007199254740997 behouden en als JSON kunnen worden ontleed. Welke recordtekst voldoet aan beide eisen?
  1. {"id":9007199254740997,"active":true}
  2. {id:"9007199254740997",active:true}
  3. {"id":"9007199254740997","active":true}
  4. {"id":'9007199254740997',"active":true}
Toon antwoordVerberg antwoord
Antwoord: C
Sleutels tussen dubbele aanhalingstekens en true in kleine letters maken het record geldige JSON, en een string behoudt elk ID-cijfer. Het grote gehele getal zonder aanhalingstekens wordt tijdens het ontleden in JavaScript afgerond, ook al is de syntaxis geldig. Sleutels zonder aanhalingstekens of enkele aanhalingstekens rond de ID doorstaan de JSON-syntaxiscontrole niet.

Vraag 10 van 10

Welke tekst wordt teruggegeven?

JSON.stringify({
  note: undefined,
  values: [undefined, NaN],
  ok: false
});
  1. '{"values":[null,null],"ok":false}'
  2. '{"note":null,"values":[null,null],"ok":false}'
  3. '{"values":[],"ok":false}'
  4. '{"values":[null,null]}'
Toon antwoordVerberg antwoord
Antwoord: A
De objecteigenschap met de waarde undefined wordt weggelaten, terwijl undefined in een array null wordt. NaN wordt ook null en de geldige booleaanse waarde false blijft behouden. Als note als null zou worden behouden, zou de arrayregel ten onrechte op een objecteigenschap worden toegepast; het verwijderen van arrayposities zou de structuur veranderen.
Set 2: Pas patronen toe en behoud ontvangende objecten10 Oefenvragen

Sla deze les op om elk antwoord te zien en elke set te oefenen.

Vraag 1 van 10

Wat geeft trip.host?.name ?? "Guest" terug?

const trip = { host: null };
  1. null
  2. undefined
  3. "Guest"
  4. Een TypeError
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 2 van 10

Wat zijn de uiteindelijke waarden van a.level en a === b?

const a = { level: 2 };
const b = a;
b.level = 5;
  1. 5 en true
  2. 2 en false
  3. 5 en false
  4. 2 en true
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 3 van 10

Wat zijn source.mode en source.layout.width daarna?

const source = { mode: "day", layout: { width: 40 } };
const copy = { ...source };
copy.mode = "night";
copy.layout.width = 60;
  1. "night" en 60
  2. "day" en 40
  3. "night" en 40
  4. "day" en 60
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 4 van 10

Welke functie kun je aan map doorgeven zodat elke aanroep tally bijwerkt?

const tally = { n: 0, tick() { return ++this.n; } };
const result = ["x", "y"].map(/* callback */);
  1. tally.tick
  2. () => tally.tick()
  3. tally.tick()
  4. () => tally.tick
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 5 van 10

Deze code wordt uitgevoerd op het hoogste niveau van een module. Wat gebeurt er als card.read() wordt aangeroepen?

const card = { title: "Basin", read: () => this.title };
  1. Er wordt een TypeError opgeworpen.
  2. De aanroep geeft "Basin" terug.
  3. De aanroep geeft undefined terug.
  4. Er wordt een ReferenceError opgeworpen.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 6 van 10

Wat zijn na next.panel.width = 90 de waarden van next.mode en base.panel.width?

const base = { mode: "wide", panel: { width: 50 } };
const next = { mode: "small", ...base, panel: { ...base.panel } };
  1. "small" en 50
  2. "wide" en 90
  3. "small" en 90
  4. "wide" en 50
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 7 van 10

Welke waarde krijgt size?

const { size = 6 } = {};
  1. undefined
  2. 6
  3. null
  4. 0
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 8 van 10

Welke array levert deze expressie op?

[...new Set(["red", "blue", "red", "green", "blue"])];
  1. ["blue", "green", "red"]
  2. ["red", "green", "blue"]
  3. ["red", "blue", "green"]
  4. ["red", "blue", "red", "green", "blue"]
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 9 van 10

Wat is de uiteindelijke waarde van loaded?

const loaded = JSON.parse('{"count":4,"tag":"a"}', (key, value) => {
  if (key === "count") return value * 2;
});
  1. undefined
  2. { count: 8, tag: "a" }
  3. { count: 8 }
  4. {}
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 10 van 10

Wat gebeurt er wanneer deze tekst wordt ontleed?

JSON.parse('{"mode":"fast","mode":"slow"}');
  1. De aanroep geeft { mode: "fast" } terug.
  2. De aanroep geeft { mode: "slow" } terug.
  3. Er wordt een SyntaxError opgeworpen.
  4. De aanroep geeft { mode: ["fast", "slow"] } terug.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Set 3: Transformeer verzamelingen en herstel gegevens10 Oefenvragen

Sla deze les op om elk antwoord te zien en elke set te oefenen.

Vraag 1 van 10

Welk object maakt de expressie?

Object.fromEntries(
  Object.entries({ north: 3, south: 5 })
    .map(([key, value]) => [key, value + 2])
);
  1. { north: 5, south: 7 }
  2. { north: 3, south: 5 }
  3. { north: 6, south: 10 }
  4. { 5: "north", 7: "south" }
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 2 van 10

Wat geeft options.limit ?? 12 terug?

const options = { limit: 0 };
  1. 12
  2. undefined
  3. 0
  4. null
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 3 van 10

Wat moet add teruggeven zodat basket.add("pear").add("fig") twee keer dezelfde mand gebruikt?

const basket = {
  items: [],
  add(item) { this.items.push(item); /* return here */ }
};
  1. this.items
  2. item
  3. this.items.length
  4. this
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 4 van 10

Welke array wordt in deze module teruggegeven?

function scale(n) { return this.factor * n; }
const twice = scale.bind({ factor: 2 });
const obj = { factor: 9, twice };
[obj.twice(3), twice.call({ factor: 5 }, 4)];
  1. [27, 20]
  2. [6, 8]
  3. [6, 20]
  4. [27, 8]
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 5 van 10

Wat wordt teruggegeven?

function combine(first, ...others) {
  return [first, others.length];
}
combine(...[7, 3, 8, 2]);
  1. [7, 4]
  2. [[7, 3, 8, 2], 0]
  3. [7, 3]
  4. [7, 2]
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 6 van 10

Wat zijn items[0].done, next[1] === items[1] en next === items?

const items = [{ id: 4, done: false }, { id: 9, done: false }];
const next = items.map(item =>
  item.id === 4 ? { ...item, done: true } : item
);
  1. true, true, false
  2. false, true, false
  3. false, false, false
  4. false, true, true
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 7 van 10

Waarom is lookup.get({ code: 8 }) undefined?

const key = { code: 8 };
const lookup = new Map([[key, "ready"]]);
  1. De opzoekactie gebruikt een andere objectreferentie.
  2. Map zet beide sleutels om in verschillende strings.
  3. Map negeert objectsleutels bij het maken van paren.
  4. De sleutel moet eerst worden omgezet in JSON-tekst.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 8 van 10

Wat zijn de grootten van a.difference(b) en a.symmetricDifference(b)?

const a = new Set([2, 4, 6]);
const b = new Set([4, 8]);
  1. 1 en 1
  2. 3 en 2
  3. 2 en 4
  4. 2 en 3
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 9 van 10

Welke tekst levert dit op?

JSON.stringify({ label: "Arc", count: 3 }, ["label"]);
  1. '{"label":"Arc","count":3}'
  2. '{"label":"Arc"}'
  3. '["label"]'
  4. '{"label":"Arc","count":null}'
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 10 van 10

Deze module wordt uitgevoerd zonder herstelcallback. Wat zijn typeof loaded.due en loaded === original?

const original = { due: new Date("2026-07-12T00:00:00.000Z") };
const loaded = JSON.parse(JSON.stringify(original));
  1. "object" en false
  2. "string" en true
  3. "object" en true
  4. "string" en false
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Set 4: Onderzoek bijwerkingen en aanroepen10 Oefenvragen

Sla deze les op om elk antwoord te zien en elke set te oefenen.

Vraag 1 van 10

Wat zijn base.inner.n, clone.inner.n en copy.inner.n aan het einde?

const base = { inner: { n: 2 } };
const copy = { ...base };
const clone = structuredClone(base);
Object.freeze(base);
copy.inner.n = 7;
clone.inner.n = 9;
  1. 2, 9, 7
  2. 9, 9, 9
  3. 2, 9, 2
  4. 7, 9, 7
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 2 van 10

Welke array geeft Object.keys(data) terug?

const data = { z: 1, "10": 2, "02": 3, "2": 4, a: 5 };
  1. ["z", "10", "02", "2", "a"]
  2. ["2", "10", "z", "02", "a"]
  3. ["02", "2", "10", "z", "a"]
  4. ["2", "02", "10", "z", "a"]
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 3 van 10

Wat is totalG en verandert load.items[1].massG ook als je heavy.massG wijzigt?

const load = { items: [
  { massG: 120, qty: 2 },
  { massG: 300, qty: 1 }
] };
const heavy = load.items.find(x => x.massG > 200);
const totalG = load.items.reduce((s, x) => s + x.massG * x.qty, 0);
heavy.massG = 350;
  1. 540; ja, de waarde wordt 350.
  2. 590; ja, de waarde wordt 350.
  3. 540; nee, de waarde blijft 300.
  4. 420; ja, de waarde wordt 350.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 4 van 10

Wat geeft b.labels() terug in deze module?

const a = {
  prefix: "A",
  names: ["oak"],
  labels() { return this.names.map(n => this.prefix + n); }
};
const b = { prefix: "B", names: ["elm"], labels: a.labels };
  1. ["Aoak"]
  2. ["Aelm"]
  3. ["Belm"]
  4. Er wordt een TypeError opgeworpen.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 5 van 10

Wat is typeof box.open?

const box = { open() { return "opened"; } };
  1. "function"
  2. "string"
  3. "object"
  4. "undefined"
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 6 van 10

Wat gebeurt er als read() en read({ prefs: null }) afzonderlijk worden aangeroepen?

function read({ prefs: { theme = "light" } = {} } = {}) {
  return theme;
}
  1. Beide aanroepen geven "light" terug.
  2. De eerste geeft "light" terug; de tweede werpt een TypeError op.
  3. De eerste werpt een TypeError op; de tweede geeft null terug.
  4. De eerste geeft undefined terug; de tweede geeft null terug.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 7 van 10

Wat is tail?

const [head, ...tail] = [6, 8, 11];
  1. [6, 8, 11]
  2. 8
  3. [11]
  4. [8, 11]
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 8 van 10

Wat zijn m.size en [...m.keys()]?

const m = new Map([["p", 1], ["q", 2]]);
m.set("p", 4);
m["r"] = 5;
m.delete("q");
m.set("q", 6);
  1. 3 en ["p", "r", "q"]
  2. 2 en ["q", "p"]
  3. 2 en ["p", "q"]
  4. 3 en ["p", "q", "r"]
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 9 van 10

Waarom mislukt JSON.parse('{"depthM":+7}')?
  1. JSON-getallen mogen niet met een plusteken beginnen.
  2. JSON-getallen mogen geen gehele getallen zijn.
  3. JSON-eigenschapsnamen mogen geen hoofdletters bevatten.
  4. JSON-objecten moeten ook een stringwaarde bevatten.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 10 van 10

Wat zijn result.count en result.total?

const result = JSON.parse('{"count":"6","total":12}',
  (key, value) => key === "count" ? Number(value) : value
);
result.total += result.count;
  1. "6" en "126"
  2. 6 en "126"
  3. 6 en 18
  4. undefined en NaN
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Set 5: Combineer gegevenskeuzes en conversieregels10 Oefenvragen

Sla deze les op om elk antwoord te zien en elke set te oefenen.

Vraag 1 van 10

Wat is Object.hasOwn(record, "old") na deze instructies?

const record = { old: undefined };
delete record.old;
  1. true
  2. false
  3. undefined
  4. Er wordt een TypeError opgeworpen.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 2 van 10

Wat zijn a === b, a.left === a.right en b.left === b.right?

const shared = { n: 1 };
const a = { left: shared, right: shared };
const b = JSON.parse(JSON.stringify(a));
  1. false, true, true
  2. true, true, true
  3. false, true, false
  4. false, false, false
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 3 van 10

Wat geeft saved() terug?

const maker = {
  n: 5,
  make() { return () => this.n; }
};
const other = { n: 8, make: maker.make };
const saved = other.make().bind({ n: 12 });
  1. 5
  2. 12
  3. undefined
  4. 8
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 4 van 10

Wat geeft fixed.apply({ offset: 30 }, [4]) terug?

function add(a, b) { return this.offset + a + b; }
const fixed = add.bind({ offset: 2 }, 7);
  1. 13
  2. 41
  3. 36
  4. NaN
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 5 van 10

Wat zijn a, b en rest?

let a = 3, b = 8;
[a, b] = [b, a];
const [, ...rest] = [a, b, 13];
  1. 8, 8, [8, 13]
  2. 8, 3, [8, 3, 13]
  3. 8, 3, [3, 13]
  4. 3, 8, [8, 13]
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 6 van 10

Wat is na publicCopy.profile.name = "New" de waarde van source.profile.name en heeft source nog steeds secret als eigen eigenschap?

const source = { secret: "s", profile: { name: "Old" } };
const { secret, ...publicCopy } = source;
  1. "Old"; ja.
  2. "New"; ja.
  3. "New"; nee.
  4. "Old"; nee.
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 7 van 10

Wat is de uiteindelijke waarde van counts.get("moss")?

const counts = new Map();
for (const word of ["moss", "fern", "moss", "moss"]) {
  counts.set(word, (counts.get(word) ?? 0) + 1);
}
  1. 1
  2. 2
  3. 4
  4. 3
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 8 van 10

Wat zijn records.size en ids.size?

const x = { id: 7 };
const records = new Set([x, x, { id: 7 }]);
const ids = new Set([...records].map(r => r.id));
  1. 2 en 1
  2. 1 en 1
  3. 3 en 1
  4. 2 en 2
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 9 van 10

Wat is typeof JSON.parse(text)?

const text = JSON.stringify('{"x":3}');
  1. "string"
  2. "object"
  3. "number"
  4. "undefined"
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Vraag 10 van 10

Een Map moet de afzonderlijke numerieke sleutel 3 en stringsleutel "3" met de waarden "n" en "s" behouden. Welk paar conversies behoudt ze via JSON?
  1. Schrijf JSON.stringify(Object.fromEntries(m)); lees met new Map(Object.entries(JSON.parse(text))).
  2. Schrijf JSON.stringify([...m]); lees met new Map(JSON.parse(text)).
  3. Schrijf JSON.stringify(m); lees met new Map(Object.entries(JSON.parse(text))).
  4. Schrijf JSON.stringify([...m.keys()]); lees met new Map(JSON.parse(text)).
Toon antwoordVerberg antwoord

Sla deze les op om dit antwoord te zien.

Kom je niet uit je eigen opgave? Huiswerkhulp

Kernbegrippen

79 Kernbegrippen, elk met een definitie

A

Aanwezigheid van een eigenschap
Aanwezigheid van een eigenschap betekent dat een sleutel aanwezig is, ongeacht of de opgeslagen waarde truthy, falsy of undefined is.
Een record met count: 0 heeft nog steeds een eigenschap count; als je die waarde als voorwaarde test, merk je de eigenschap niet op.
Aanwezigheidscontrole
Een aanwezigheidscontrole vraagt of een sleutel of waarde in een verzameling aanwezig is, onafhankelijk van de gegevens die onder die sleutel zijn opgeslagen.
map.has(key) kan een bestaand sleutel-waardepaar vinden, ook als map.get(key) undefined teruggeeft.
Afgeleide waarde
Een afgeleide waarde wordt berekend uit andere opgeslagen gegevens, zoals een totaal uit afzonderlijke regels, en kan verouderen als ze afzonderlijk wordt opgeslagen.
Als je de afstand van een route uit de routeonderdelen berekent, blijft het resultaat consistent nadat een onderdeel verandert.
apply
apply voert een functie direct uit met een expliciete this-waarde en een array met de gewone argumenten.
format.apply(reading, ["m", 2]) levert hetzelfde ontvangende object en dezelfde waarden als format.call(reading, "m", 2).
Array-indexsleutel
Een array-indexsleutel is een standaardstring voor een geheel getal van 0 tot en met 4294967294, die vóór andere eigen stringsleutels numeriek wordt geordend.
De sleutel "3" komt in Object.keys vóór "12"; "03" blijft tussen de gewone stringsleutels staan.
Arraydestructurering
Arraydestructurering leest waarden van opeenvolgende posities uit een itereerbare waarde in een patroon met blokhaken.
const [low, high] = bounds; vertrouwt erop dat bounds de lagere waarde vóór de hogere waarde plaatst.

B

Berekende eigenschapsnaam
Een berekende eigenschapsnaam evalueert een expressie tussen blokhaken om een eigenschap in een literal een naam te geven.
Met const code = "es"; maakt { [code]: "Hola" } een eigenschap met de naam "es".
Bijwerking zonder mutatie
Een bijwerking zonder mutatie bouwt nieuwe containers voor de gegevens die veranderen en behoudt de oorspronkelijke containers en eventuele ongewijzigde gedeelde waarden.
Een map-callback kan voor het gewijzigde record een kopie met spreadsyntaxis teruggeven en elk ongewijzigd record opnieuw gebruiken.
bind
bind geeft een nieuwe functie terug met een vaste this-waarde en optionele vooraanstaande argumenten; de uitvoering wacht totdat de nieuwe functie wordt aangeroepen.
Met const next = meter.step.bind(meter); maak je een callback die meter als ontvangend object behoudt.
Blokhaaknotatie
Blokhaaknotatie evalueert de expressie tussen blokhaken om een eigenschapssleutel te selecteren.
Met const field = "heightM"; selecteert person[field] de lengtemeting van de persoon.

C

call
call voert een functie direct uit met een expliciete this-waarde, gevolgd door gewone argumenten die één voor één worden doorgegeven.
format.call(reading, "m", 2) geeft format het ontvangende object reading en twee afzonderlijke argumenten.
Circulaire referentie
Een circulaire referentie is een pad van objectreferenties dat terugkeert naar een object dat al op dat pad staat en dat gewone JSON niet kan coderen.
Als je record.self = record toevoegt, werpt het gewone JSON.stringify voor dat record een TypeError op.

D

Deelverzameling
Een deelverzameling is een verzameling waarvan elke waarde ook bij een andere verzameling hoort, zelfs als de twee verzamelingen gelijk zijn.
Een Set met vereiste machtigingen is alleen een deelverzameling van de verleende machtigingen als elke vereiste waarde is verleend.
Diepe kopie
Een diepe kopie maakt naast een nieuwe buitenste waarde ook onafhankelijke geneste gegevens, voor zover de kopieermethode de typen ondersteunt.
Na een ondersteunde structuredClone blijft het oorspronkelijke geneste veld ongewijzigd als je het gekopieerde veld bewerkt.
Doorsnede
Een doorsnede bevat alleen de waarden die in beide verzamelingen aanwezig zijn en laat waarden weg die in slechts één ervan voorkomen.
De doorsnede van actieve ID's en goedgekeurde ID's levert de ID's op die aan beide aanwezigheidsvoorwaarden voldoen.

E

Eigen eigenschap
Een eigen eigenschap hoort rechtstreeks bij een object, zodat een controle op eigen eigenschappen geen eigenschappen meeneemt die via overerving worden bereikt.
Object.hasOwn({}, "toString") is false, ook al is "toString" in {} true.
Eigenschap
Een eigenschap koppelt een objectsleutel aan een waarde, waaronder gegevens of een functie.
De eigenschap active in { active: false } bestaat, ook al is haar waarde de booleaanse waarde false.
Escapesequentie
Een escapesequentie gebruikt een backslash en daaropvolgende tekens om een speciaal teken of een UTF-16-code-eenheid binnen een JSON-string weer te geven.
Als je een bericht met een regeleinde omzet in een string, wordt een escapesequentie geschreven in plaats van een letterlijk regeleinde binnen de string.

G

Geleende methode
Een geleende methode is een gewone functie die uit een ander object is gehaald en via een nieuw ontvangend object wordt gebruikt zonder de functie zelf te veranderen.
De toewijzing b.read = a.read zorgt ervoor dat b.read() de gegevens van b gebruikt wanneer de functie via this leest.
Genest patroon
Een genest patroon selecteert waarden uit een binnenste structuur terwijl de buitenste structuur wordt uitgepakt.
const { owner: { name } } = item; heeft een object owner nodig en declareert alleen name.
Geneste gegevens
Bij geneste gegevens staan objecten of arrays binnen andere objecten of arrays, zodat een pad meerdere stappen moet volgen om een waarde te bereiken.
report.readings[0].tempC leest een lijst, het eerste record daarvan en vervolgens een temperatuurveld.
Gewone functieaanroep in strikte modus
Een gewone functieaanroep in strikte modus roept een strikte gewone functie aan zonder een ontvangend object op te geven, zodat de this-waarde undefined is.
Als je een methode loskoppelt in f en f() in een module aanroept, kan dat mislukken wanneer de functie this.name probeert te lezen.
globalThis
globalThis biedt een standaardmanier om naar het globale object te verwijzen, dat niet-strikte gewone functies bij een gewone aanroep gebruiken.
Het globale object van een browser is window, maar een gewone functieaanroep in strikte modus krijgt nog steeds undefined als this.

H

Heen-en-terugconversie
Een heen-en-terugconversie schrijft gegevens in een weergave en leest ze terug, waarbij alleen de informatie behouden blijft die die weergave kan uitdrukken.
Een heen-en-terugconversie via JSON maakt nieuwe objecten en geeft een Date terug als tekst, tenzij een conversie het type herstelt.
Hernoemingspatroon
Een hernoemingspatroon leest een eigenschap met een dubbele punt in onder een andere lokale naam.
const { title: label } = page; maakt label aan zonder een variabele met de naam title te declareren.
Herstelcallback
Een herstelcallback is een callback van JSON.parse die waarden na hun onderliggende waarden transformeert en de retourwaarden gebruikt om de bezochte waarden te vervangen of te verwijderen.
Een herstelcallback kan een bekend datumveld herstellen en alle overige waarden ongewijzigd teruggeven.

I

Inspringargument
Het inspringargument is het derde argument van stringify en bepaalt welke spaties of korte string worden gebruikt om geneste JSON-tekst op te maken.
Als je null als vervangingsargument en 2 als derde argument doorgeeft, gebruikt elk genest niveau twee spaties.
Invoegvolgorde
Invoegvolgorde is de volgorde waarin verschillende sleutels of waarden voor het eerst in een verzameling terechtkomen, die bij iteratie over Map en Set behouden blijft.
Als je een sleutel-waardepaar in een Map bijwerkt, behoudt het zijn plaats; als je het verwijdert en de sleutel opnieuw invoegt, komt die achteraan.
Itereerbare waarde
Een itereerbare waarde levert een reeks waarden aan bewerkingen zoals for...of of spreadsyntaxis voor arrays.
Arrays, strings, Maps en Sets kunnen op deze manier worden uitgepakt; een gewoon record niet.

J

JSON
JSON is een taalonafhankelijk tekstformaat dat objecten, arrays, strings, getallen, booleaanse waarden en null met strikte syntaxis weergeeft.
De tekst {"ready":true} beschrijft een record, terwijl true op zichzelf ook een geldige volledige JSON-tekst is.
JSON-string
Een JSON-string bestaat uit tekstgegevens tussen dubbele aanhalingstekens, met escapesequenties voor tekens zoals aanhalingstekens en regeleinden.
Een tekstwaarde met een aanhalingsteken heeft binnen de omringende dubbele JSON-aanhalingstekens een escapesequentie nodig.
JSON.parse
JSON.parse leest JSON-tekst en geeft de weergegeven JavaScript-waarde terug; bij ongeldige tekst werpt de functie een SyntaxError op.
Als je een record met de numerieke waarde 4 voor count ontleedt, kun je ermee rekenen, terwijl een count tussen aanhalingstekens een string blijft.
JSON.stringify
JSON.stringify serialiseert ondersteunde JavaScript-waarden naar JSON-tekst en kan daarbij gegevens selecteren en leesbare inspringing toevoegen.
JSON.stringify(settings, null, 2) schrijft een beter leesbare vorm zonder de weergegeven instellingen te veranderen.

L

Lexicale this
Lexicale this is de omringende this-waarde die een pijlfunctie behoudt van de plaats waar ze is gemaakt, ongeacht een later ontvangend object of een latere binding.
Een pijlfunctie die binnen een uitgevoerde methode is gemaakt, kan het object van die methode behouden tijdens een arraycallback.
Losgekoppelde methode
Een losgekoppelde methode is een functie die uit een object is gelezen en wordt doorgegeven of opgeslagen zonder het object in de latere aanroepexpressie te behouden.
const read = sensor.read; behoudt de functie, maar read() levert sensor niet als ontvangend object.

M

Map
Een Map is een verzameling sleutel-waardeparen met sleutels van elk type, die de volgorde behoudt waarin de sleutels voor het eerst zijn toegevoegd.
De numerieke sleutel 5 en de stringsleutel "5" blijven afzonderlijke sleutel-waardeparen wanneer ze in dezelfde Map worden opgeslagen.
Map.groupBy
Map.groupBy is een nieuwere methode die itereerbare items in arrays binnen een Map groepeert en daarbij het type en de identiteit van groepssleutels behoudt.
Als je records groepeert op een gedeeld eigenaarobject, kun je met dezelfde referentie naar de eigenaar de bijbehorende groep ophalen.
Methode
Een methode is een eigenschap met een functie als waarde, die via een object wordt aangeroepen.
De aanroep tracker.advance() voert de actie van de tracker uit, terwijl het lezen van tracker.advance een functie teruggeeft.
Methoden aaneenschakelen
Methoden aaneenschakelen betekent dat je een methode aanroept op de waarde die de vorige aanroep heeft teruggegeven.
list.add("a").add("b") werkt wanneer de eerste aanroep een object met de volgende methode add teruggeeft.

O

Object.freeze
Object.freeze voorkomt toevoegingen, verwijderingen en wijzigingen van de eigen eigenschappen van een object, maar bevriest geen geneste objecten.
In strikte code werpt een toewijzing aan status op het hoogste niveau van een bevroren record een TypeError op.
Object.fromEntries
Object.fromEntries maakt een object uit sleutel-waardeparen en is daardoor nuttig na een transformatie van paren of van een geschikte Map.
Door de waarde van elk paar te transformeren en het object opnieuw op te bouwen, kun je een heel record met metingen converteren.
Object.groupBy
Object.groupBy is een nieuwere methode die itereerbare items in arrays groepeert onder door een callback gekozen sleutels in een object zonder prototype.
Als je taken op status groepeert, krijg je één array voor voltooide taken en een andere voor taken die nog moeten worden uitgevoerd.
Objectdestructurering
Objectdestructurering leest geselecteerde eigenschappen in variabelen door hun namen te koppelen.
const { city, tempC } = reading; maakt twee lokale variabelen uit een weerrecord.
Objectidentiteit
Objectidentiteit is het onderscheid tussen één bepaald object en elk ander object, ongeacht overeenkomende veldwaarden.
Twee afzonderlijk gemaakte records met id: 9 zijn bij vergelijking met === ongelijk, ondanks overeenkomende gegevens.
Objectliteral
Een objectliteral maakt rechtstreeks een object met accolades en sleutel-waardeparen als eigenschappen.
const reading = { tempC: 22 }; maakt een record met één temperatuurmeting.
Omhullende pijlfunctie
Een omhullende pijlfunctie is een pijlfunctie als callback waarvan het functielichaam later de bedoelde methodeaanroep uitvoert, zodat het ontvangende object van die aanroep expliciet blijft.
Als je () => counter.tick() aan map doorgeeft, roept elke callback tick via het object counter aan.
Ontvangend object
Een ontvangend object is het object dat bij een gewone methodeaanroep als this wordt opgegeven.
In account.describe() is account het ontvangende object waarvan de methode de velden leest.
Oppervlakkige kopie
Een oppervlakkige kopie maakt een nieuw buitenste object of een nieuwe buitenste array en behoudt de referenties naar eventuele geneste objecten daarin.
Als je het geneste adres van een gekopieerd record bijwerkt, kan ook het gedeelde adres van het oorspronkelijke record veranderen.
Optieobject
Een optieobject geeft benoemde instellingen door aan een functie in plaats van te vertrouwen op argumentposities.
Bij een functie die { color, size } ontvangt, kunnen aanroepers aangeven wat elke instelling betekent zonder een vaste volgorde te gebruiken.
Optionele ketenvorming
Optionele ketenvorming stopt een eigenschapstoegang, toegang via een index of aanroep wanneer de gecontroleerde waarde null of undefined is, en levert undefined op.
record.owner?.name staat een ontbrekende owner toe zonder een naam uit undefined te proberen te lezen.
Overgeslagen positie
Een overgeslagen positie neemt een waarde op zonder die een naam te geven in een arraydestructureringspatroon.
const [, second] = colors; slaat de eerste kleur over en geeft alleen de volgende geleverde waarde een naam.

P

Partiële toepassing
Partiële toepassing legt nu enkele argumenten vast om een functie te maken die de resterende argumenten ontvangt wanneer ze later wordt aangeroepen.
multiply.bind(null, 4) maakt een functie die haar volgende argument met vier vermenigvuldigt.
Puntnotatie
Puntnotatie selecteert de letterlijke eigenschapsnaam na een punt.
profile.name selecteert altijd de eigenschap met de naam "name", ook als er een variabele met de naam name bestaat.

R

Referentie
Een referentie verbindt een variabele of eigenschap met een object, zodat meerdere namen dezelfde onderliggende waarde kunnen bereiken en wijzigen.
De toewijzing const backup = record; geeft een extra manier om record te bereiken zonder de velden te kopiëren.
Rest-element in een arraypatroon
Een rest-element in een arraypatroon verzamelt resterende waarden in een nieuwe array en moet het patroon afsluiten.
const [leader, ...others] = names; scheidt de eerste naam van een array met de resterende namen.
Restparameter
Een restparameter verzamelt resterende functieargumenten in een echte array en moet de laatste parameter in de declaratie zijn.
function total(...values) kan reduce gebruiken op values, ook als de aanroep geen argumenten doorgeeft.
Restsyntaxis voor objecten
Restsyntaxis voor objecten verzamelt eigen opsombare eigenschappen die nog niet in een destructureringspatroon zijn genoemd in een nieuw, oppervlakkig object.
const { password, ...publicRecord } = user; laat user intact en laat password weg uit de kopie.

S

Serialisatie
Serialisatie zet actieve waarden om in een weergave die kan worden opgeslagen of uitgewisseld, zoals JSON-tekst die door stringify is gemaakt.
Een instellingenobject moet worden geserialiseerd voordat een bestemming die alleen tekst accepteert de structuur kan ontvangen.
Set
Een Set is een verzameling unieke waarden van elk type die bij iteratie de invoegvolgorde behoudt en geen posities met indexen heeft.
Als je "ready" twee keer toevoegt, blijft één waarde behouden, terwijl twee afzonderlijke overeenkomende records allebei behouden blijven.
Sleutel-waardepaar
Een sleutel-waardepaar is een reeks van twee items waarvan de eerste waarde een eigenschapssleutel of een sleutel van een verzameling is en de tweede waarde de bijbehorende gegevens bevat.
Object.entries({ lake: 5 }) levert [["lake", 5]] op, klaar voor een lus over sleutel en waarde.
Sleutel-waardepaar in een Map
Een sleutel-waardepaar in een Map koppelt één sleutel aan één waarde en wordt met Map-methoden beheerd, onafhankelijk van gewone objecteigenschappen.
stock.set("tea", 4) wijzigt een sleutel-waardepaar; stock["tea"] = 4 wijzigt een gewone eigenschap.
Spreadsyntaxis voor itereerbare waarden
Spreadsyntaxis voor itereerbare waarden vouwt een itereerbare waarde uit tot afzonderlijke arrayelementen of argumenten voor een aanroep en leest de waarden achtereenvolgens.
Math.max(...measurements) geeft elk arrayitem als afzonderlijk argument door aan de functie.
Spreadsyntaxis voor objecten
Spreadsyntaxis voor objecten kopieert eigen opsombare eigenschappen naar een nieuwe literal, waarbij latere vermeldingen eerdere waarden met dezelfde sleutel overschrijven.
{ ...base, active: true } kopieert base en levert daarna de uiteindelijke waarde voor active.
Standaardwaarde bij destructurering
Een standaardwaarde bij destructurering vervangt een geselecteerde waarde undefined, ook bij een ontbrekend veld of een ontbrekende positie.
In const { count = 2 } = { count: null }; blijft de expliciete null behouden ondanks de standaardwaarde.
structuredClone
structuredClone kopieert ondersteunde geneste JavaScript-waarden, waaronder circulaire structuren, maar accepteert geen functiewaarden.
Een record met gewone arrays kan worden gekloond; als het een methode bevat, veroorzaakt dat een DataCloneError.
Structuurcontrole
Een structuurcontrole verifieert vóór gebruik of een ontlede waarde de velden, containersoorten en waardetypen heeft die het programma nodig heeft.
Geldige JSON met een string als count moet nog worden gecontroleerd voordat een programma dat veld als getal behandelt.
Symmetrisch verschil
Een symmetrisch verschil bevat waarden die in precies één van twee verzamelingen aanwezig zijn en sluit elke gedeelde waarde uit.
Als je twee Sets met labels zo vergelijkt, vind je labels die bij één lijst horen maar niet bij beide.
SyntaxError
Een SyntaxError geeft ongeldige syntaxis aan, zoals ongeldige tekst die aan JSON.parse wordt doorgegeven.
Een komma aan het einde van externe JSON kun je met try...catch opvangen, zodat het programma de fout kan afhandelen.

T

Terugval bij null of undefined
Terugval bij null of undefined levert alleen een terugvalwaarde wanneer de linkeroperand null of undefined is, en behoudt andere falsy-waarden.
settings.volume ?? 1 behoudt een expliciet volume van nul, terwijl settings.volume || 1 dat vervangt.
this
Het sleutelwoord this duidt de huidige context van een functie aan; gewone functies krijgen die meestal via de aanroep en pijlfuncties behouden een buitenste context.
Dezelfde ongebonden gewone leesmethode kan verschillende objecten lezen als ze via verschillende ontvangende objecten wordt aangeroepen.
toJSON
Een methode toJSON geeft de gekozen weergave van een object terug die geschikt is voor JSON; stringify schrijft die in plaats van het oorspronkelijke object.
Een meetobject kan een kleiner gewoon record teruggeven met de velden die voor uitwisseling zijn bedoeld.

V

Veilig geheel getal
Een veilig geheel getal is een geheel getal van -9.007.199.254.740.991 tot en met 9.007.199.254.740.991; binnen dat bereik houdt JavaScript Number elk geheel getal afzonderlijk en exact.
Een identifier buiten het veilige bereik kan als JSON-string worden verstuurd om elk cijfer te behouden.
Vereniging
Een vereniging bevat elke waarde die in minstens één van twee verzamelingen aanwezig is, waarbij gedeelde waarden maar één keer in de resulterende Set voorkomen.
Als de ene groep Ana en Bo bevat en de andere Bo en Cai, bevat hun vereniging alle drie de personen.
Verkorte eigenschapsnotatie
De verkorte eigenschapsnotatie ontleent de naam en waarde van een eigenschap aan een variabele met dezelfde naam.
Met een variabele city maakt de literal { city } hetzelfde veld als { city: city }.
Verkorte methodenotatie
De verkorte methodenotatie definieert een gewone methode in een literal rechtstreeks met haar naam, parameters en functielichaam.
Het lid reset() { this.n = 0; } definieert een actie zonder afzonderlijke dubbele punt en sleutelwoord function.
Verschil
Een verschil bevat waarden uit een eerste verzameling die ontbreken in een tweede, zodat het resultaat kan veranderen als je de verzamelingen omwisselt.
active.difference(blocked) behoudt actieve waarden die niet in de Set blocked voorkomen.
Vervangingsargument
Een vervangingsargument is het tweede argument van stringify: een array met eigenschapsnamen die moeten worden opgenomen of een functie die bezochte waarden transformeert.
Als de functie voor een privéobjecteigenschap undefined teruggeeft, wordt die weggelaten; als ze de oorspronkelijke waarde teruggeeft, blijven andere gegevens behouden.

W

WeakMap
Een WeakMap koppelt waarden aan objecten of niet-geregistreerde symbolen als sleutels, zonder sleutels die verder onbereikbaar zijn in leven te houden.
Een WeakMap kan metagegevens aan een object koppelen zonder velden aan dat object toe te voegen of een lijst met sleutel-waardeparen beschikbaar te stellen.
WeakSet
Een WeakSet houdt bij welke objecten of niet-geregistreerde symbolen aanwezig zijn zonder leden die verder onbereikbaar zijn in leven te houden en kan niet worden doorlopen.
Een WeakSet kan verwerkte objecten markeren zonder ze vast te houden alleen omdat ze ooit zijn verwerkt.

Over deze les

Door StudeliFout melden

Maak je eigen Studiemateriaal

Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.

Aan de slag