Sådan får du fat på reference vs værdi i JavaScript

Denne artikel diskuterer, hvordan de forskellige JavaScript-datatyper opfører sig, når de er tildelt en variabel. Afhængig af datatypen tildeles hukommelse forskelligt for at gemme den. Det reserverer muligvis et nyt rum til at gemme en kopi af værdien, eller det opretter måske slet ikke en kopi og peger bare på den eksisterende værdi (reference).
Her er mine notater taget, mens jeg fulgte Javascript30-kurset af Wes Bos.
Tal, strenge og booleanske
I JavaScript primitive Typer såsom undefined
, null
, string
, number
, boolean
og symbol
er gået i værdi.
let name = ‘Marina’;let name2 = name;
console.log({name, name2}); >> { name: ‘Marina’, name2: ‘Marina’ }
name = ‘Vinicius’;
console.log({name, name2});>> { name: ‘Vinicius’, name2: ‘Marina’ }

Når variablen name
er tildelt, 0x001
er der reserveret et mellemrum i hukommelsen med en adresse til at gemme denne værdi. Variablen name
peger derefter på den adresse. Variablen name2
indstilles derefter til lige name
. Et nyt mellemrum i hukommelsen med en ny adresse 0x002
tildeles og gemmer en kopi af den værdi, der er gemt i den adresse, der name
peger på.
Så når vi vil ændre værdien af name
, ændres den gemte værdi name2
ikke, da det er en kopi, der er gemt et andet sted.
Objekter og arrays
Objekter i JavaScript sendes som reference. Når mere end en variabel er indstillet til at gemme enten en object
, array
eller function
, peger disse variabler på det samme tildelte plads i hukommelsen.
const animals = ['Cat', 'Dog', 'Horse', 'Snake'];
let animals2 = animals;console.log({animals, animals2});>>{ animals: ['Cat', 'Dog', 'Horse', 'Snake'], animals2: ['Cat', 'Dog', 'Horse', 'Snake']}
animals2[3] = 'Wale';console.log(animals, animals2);>>{ animals: ['Cat', 'Dog', 'Horse', 'Wale'], animals2: ['Cat', 'Dog', 'Horse', 'Wale']}

Når animals
er indstillet til at gemme en matrix, tildeles hukommelse, og en adresse er knyttet til den variabel. Derefter animals2
er indstillet til lige animals
. Da animals
lagrer en matrix i stedet for at oprette en kopi af den matrix og en ny adresse i hukommelsen, animals2
er den simpelthen peget på det samme objekt i den eksisterende adresse. På den måde animals2
reflekteres eventuelle ændringer i animals
, fordi de peger på den samme placering.
Du ser den samme adfærd for objekter:
const person = { name: 'Marina', age: 29};
let femme = person;femme.age = 18;
console.log({person, femme});>>{ person: { name: 'Marina', age: 18 }, femme: { name: 'Marina', age: 18 }}
Kopiering af objekter og arrays
Da en simpel opgave ikke er nok til at fremstille en kopi af et objekt, kan det opnås ved andre tilgange:
Arrays
skive()
let animals2 = animals.slice();animals2[3] = 'Shark';
concat ()
let animals3 = [].concat(animals);animals3[3] = 'Tiger';
spredning (ES6)
let animals4 = [...animals];animals4[3] = 'Lion';
Ændringer påvirker kun det modificerede objekt:
console.log({animals, animals2, animals3, animals4});>>{ animals: ['Cat', 'Dog', 'Horse', 'Snake'], animals2: ['Cat', 'Dog', 'Horse', 'Shark'], animals3: ['Cat', 'Dog', 'Horse', 'Tiger'], animals4: ['Cat', 'Dog', 'Horse', 'Lion']}
Objekter
tildele ()
let human = Object.assign({}, person, { age: 20 });
console.log(person, human);>>{ person: { name: 'Marina', age: 29 }, human: { name: 'Marina', age: 20 }}
Dyb klon
Det er vigtigt at bemærke, at disse metoder kun er et niveau dybt. For dybe kloner er der en rynket metode. Brug forsigtigt.
let femme3 = JSON.parse(JSON.stringify(person));femme3.name = 'Leslie';
console.log(person, femme3);>>{ person: { name: 'Marina', age: 29 }, femme3: { name: 'Leslie', age: 29 }}
Referencer
- WesBos - Javascript 30
- Du kender ikke JS: Scope & Closures af Kyle Simpson
Oprindeligt offentliggjort på marina-ferreira.github.io.