Pass by Value vs Pass By Reference i JavaScript

om du är ny på JavaScript är chansen att du redan har stött på något av det roliga beteendet som detta språk har att erbjuda (utställning a). I början, dessa konstiga egenheter kan verka löjligt och frustrerande, men jag lovar att det finns en metod bakom allt detta galenskap.

en av de svåraste hindren att övervinna, enligt min ödmjuka åsikt, är skillnaden mellan att passera genom värde vs att passera genom referens. Varför är detta koncept så knepigt? Till att börja med kan du säkert komma ganska långt utan att verkligen förstå hur JavaScript interagerar med primitiva värden och referensvärden. Detta kan, och oftare än inte, kommer att resultera i massor av buggar som är svåra att spåra och irriterande att fixa. För det andra är detta ett koncept som kommer att komma upp i tekniska intervjuer, så att inte förstå det kommer att räknas som en stor röd flagga mot dig.

Frukta inte, medläsare! Låt utbildningen börja …

primitiva datatyper

i JavaScript kan vi dela upp datatyper i två olika hinkar, primitiva datatyper och objekt.

diagram som illustrerar de primitiva datatyperna eller värdena och objekttyperna eller referensvärdena

det finns sex primitiva datatyper i JavaScript: string, number, boolean, undefined, null, och symbol från och med ES6.

primitiva datatyper skickas eller kopieras efter värde och är oföränderliga, vilket innebär att det befintliga värdet inte kan ändras hur en array eller ett objekt kan. Låt oss ta en titt på koden nedan för att se detta i aktion.

skapad med jsbin.com

här har vi skapat två variabler, x = 10 och y = x. Eftersom 10 är ett tal och ett primitivt värde, när vi ställer in y = x kopierar vi faktiskt värdet, dvs 10, och tilldelar det till y. Vi kan också visualisera detta med hjälp av diagrammet nedan.

om vi skulle ändra värdet på x skulle vi se att ybehåller sitt värde på 10. Återigen beror detta på att primitiva värden kopieras, så yvärde är oberoende av xvärde. Tänk på det som att göra en kopia av en bild. När du har gjort kopian har du två identiska bilder: ett original och en fax. Om du skulle skära originalet i hälften skulle bara originalet ändras och faxen skulle förbli exakt densamma.

vi skrev över värdet på x Men y förblir detsamma

referensobjekt

objekt skickas å andra sidan genom referens och pekar på en plats i minnet för värdet, inte själva värdet. Låt oss ta en titt på detta i vår kod.

variablerna x och y pekar nu på objekt snarare än primitiva datatyper

i det här exemplet är x nu ett objekt som pekar på {dog: "poodle"}. När vi skapar variabeln y och tilldelar den värdet x, kan vi nu utnyttja de olika egenskaperna hos x som inkluderar värdet för dog, dvs "poodle". Det verkar som exakt samma logik som används för primitiva värden, men låt oss ta en titt på vårt handy-dandy-diagram nedan för att se den subtila men viktiga skillnaden.

både x och y pekar på en (uppbyggd) adress i minnet som lagrar en referens till objektet

nu ser det här diagrammet lite annorlunda ut än när våra variabler x och y höll primitiva datatyper. I den här versionen ser vi att värdena för både x och y inte är datatyper utan referenser till en adress i minnet, samma adress faktiskt! Låt oss nu titta på vad som händer med x om vi lägger till en ny egenskap av size till y

x returnerar fortfarande ett objekt men nu har det en extra egenskap av size också! Återigen beror detta på att både x och y pekar på samma referensobjekt, så alla ändringar som görs i en variabel kommer att synas i den andra.

diagram illustrerar hur en förändring i y uppdaterar referensvärdet som delas med x

för att hjälpa mig att komma ihåg detta koncept gillar jag att tänka på referensvärden som ett hus och variablerna som människor som bor i det huset. Alla invånare (variabler) kan säga ”Jag har ett hus” och peka på samma hus. Om en enda invånare bestämmer sig för att de vill måla huset gult, har alla invånare nu ett gult hus eftersom det delas.

Låt oss ta en titt på ytterligare ett exempel som innehåller en mängd referensobjekt.

i den här koden börjar vi med en variabel person som innehåller egenskaper name, ageoch hobbies. När vi skriver ut det här objektet till konsolen får vi exakt vad vi förväntar oss — samma objekt som vi just skapade.

därefter har vi en funktion som heter changePerson som tar in ett argument, gör några ändringar och returnerar sedan ett objekt. När vi skapar variabeln thirdPerson, åberopar vi funktionenchangePerson genom att skicka vårt ursprungliga objekt av person in i den. Den intressanta biten är vad som händer när vi skriver ut till konsolen thirdPerson och person igen.

Observera att console.log(thirdPerson) returnerar ett helt nytt objekt med nya egenskaper. Titta nu på vad console.log(person) returnerar. Detta liknar vårt ursprungliga objekt men det innehåller nya egenskapsvärden som introducerades i vår changePerson – funktion.

kontrollera jämlikhet

slutligen, låt oss ta en titt på hur primitiva datatyper och referensobjekt beter sig med jämställdhetsoperatörer.

när det gäller primitiva datatyper spelar det ingen roll vad som är till höger om = – tecknet så länge värdena är desamma. Vi kan se detta ovan med variabler a och b som skrivs annorlunda men utvärderar till samma värde när vi använder ===, den strikta jämställdhetsoperatören.

motsatsen är sant i det andra exemplet för dog och cat. Även om det kan tyckas att de innehåller identiska värden, är en array och ett referensobjekt, vilket betyder att === kontrollerar om både dog och cat har samma referens till värdet i minnet. Å andra sidan är bird === dog sant eftersom de delar samma referensobjekt.

hund och fågel delar samma referens medan katt inte trots att ha en identisk array

slutsats

och det avslutar vår introduktion till pass by value vs pass by reference. Det finns fler ämnen som kan täckas under detta paraply grundläggande, inklusive vad som händer när en referens skrivs över eller förloras, hur man kopierar en referens för att skapa ett nytt objekt och se till att kopian är en djup kopia, bara för att nämna några. Jag skulle rekommendera att kolla in de resurser jag använde nedan som går in i några av dessa ytterligare ämnen mer detaljerat.

Lämna ett svar

Din e-postadress kommer inte publiceras.