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, booleanog symboler 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 nameer tildelt, 0x001er der reserveret et mellemrum i hukommelsen med en adresse til at gemme denne værdi. Variablen namepeger derefter på den adresse. Variablen name2indstilles derefter til lige name. Et nyt mellemrum i hukommelsen med en ny adresse 0x002tildeles og gemmer en kopi af den værdi, der er gemt i den adresse, der namepeger på.

Så når vi vil ændre værdien af name, ændres den gemte værdi name2ikke, 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, arrayeller 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 animalser indstillet til at gemme en matrix, tildeles hukommelse, og en adresse er knyttet til den variabel. Derefter animals2er indstillet til lige animals. Da animalslagrer en matrix i stedet for at oprette en kopi af den matrix og en ny adresse i hukommelsen, animals2er den simpelthen peget på det samme objekt i den eksisterende adresse. På den måde animals2reflekteres 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.