Pass by Value vs Pass by Reference in JavaScript

ha még nem ismeri a Javascriptet, akkor valószínű, hogy már belefutott néhány vicces viselkedésbe, amelyet ez a nyelv kínál (a kiállítás). Eleinte ezek a furcsa furcsaságok nevetségesnek és frusztrálónak tűnhetnek, de ígérem, hogy van egy módszer az őrület mögött.

szerény véleményem szerint az egyik legnehezebb akadály, amelyet le kell küzdeni, a különbség az érték szerinti átadás vs a referencia átadása között. Miért olyan trükkös ez a koncepció? Először is, biztosan elég messzire juthatsz anélkül, hogy igazán megértenéd, hogy a JavaScript hogyan működik együtt a primitív értékekkel és a referenciaértékekkel. Ez, és gyakrabban, mint nem, egy csomó hibát eredményez, amelyeket nehéz nyomon követni és bosszantó javítani. Másodszor, ez egy olyan koncepció, amely technikai interjúkban fog megjelenni, így ha nem érti, akkor hatalmas vörös zászlónak számít ellened.

ne félj, kedves olvasó!

primitív adattípusok

a JavaScript-ben az adattípusokat két különböző vödörre oszthatjuk, primitív adattípusokra és objektumokra.

a primitív adattípusokat vagy értékeket, valamint az objektumtípusokat vagy referenciaértékeket bemutató diagram

hat primitív adattípus van a JavaScriptben: string, number, boolean, undefined, null, és symbol az ES6-tól.

a primitív adattípusok érték szerint kerülnek átadásra vagy másolásra, és megváltoztathatatlanok, ami azt jelenti, hogy a meglévő érték nem változtatható meg úgy, ahogy egy tömb vagy objektum képes. Vessünk egy pillantást az alábbi kódra, hogy ezt működés közben láthassuk.

létrehozva jsbin.com

itt két változót hoztunk létre, x = 10és y = x. Mivel a 10 egy szám és egy primitív érték, amikor a y = x értéket állítjuk be, valójában átmásoljuk az értéket, azaz 10, és hozzárendeljük a y – hez. Ezt az alábbi táblázat segítségével is megjeleníthetjük.

ha megváltoztatnánk a x értékét, azt látnánk, hogy a y megtartja 10értékét. Ez azért van, mert a primitív értékek másolódnak, így a yértéke független a x értékétől. Gondolj rá úgy, mintha fénymásolatot készítenél egy képről. A másolat elkészítése után két azonos kép van: egy eredeti és egy fax. Ha kettévágnánk az eredetit, csak az eredetit változtatnánk meg, és a fax pontosan ugyanaz maradna.

felülírtuk az X értékét, de y változatlan marad

Referenciaobjektumok

az objektumokat viszont referenciaként adjuk át, és az érték egy helyére mutatnak a memóriában, nem magára az értékre. Vessünk egy pillantást erre a kódunkban.

az x és y változók most az objektumokra mutatnak, nem pedig a

primitív adattípusokra ebben a példában a x most egy objektum, amely {dog: "poodle"} – re mutat. Amikor létrehozzuk a y változót, és x értéket rendelünk hozzá, most már képesek vagyunk a x különböző tulajdonságaira támaszkodni, amelyek tartalmazzák a dog értékét, azaz "poodle". Úgy tűnik, hogy ez pontosan ugyanaz a logika, amelyet a primitív értékeknél használnak, de vessünk egy pillantást az alábbi praktikus-dandy diagramra, hogy lássuk a finom, de fontos különbséget.

mind az x, mind az y egy (kitalált) címre mutat a memóriában, amely a

objektumra való hivatkozást tárolja. Ebben a verzióban azt látjuk, hogy mind a x, mind a y értékei nem adattípusok, hanem a memóriában lévő címekre való hivatkozások, valójában ugyanaz a cím! Most vessünk egy pillantást arra, hogy mi történik x ha hozzáadunk egy új tulajdonságot size nak nek y

x még mindig visszaad egy objektumot, de most van egy további tulajdonsága size is! Ismét azért, mert mind a x, mind a y ugyanarra a referenciaobjektumra mutat, így az egyik változóban végrehajtott változtatások a másikban láthatók lesznek.

a diagram bemutatja, hogy az y változása hogyan frissíti az X

– vel megosztott referenciaértéket, hogy segítsen emlékezni erre a koncepcióra, szeretem a referenciaértékeket házként, a változókat pedig az abban a házban élő emberekként gondolni. Minden lakó (változó) mondhatja, hogy “van egy házam”, és ugyanarra a házra mutat. Ha egyetlen lakos úgy dönt, hogy sárgára akarja festeni a házat, akkor az összes lakónak most sárga háza van, mert megosztják.

vessünk egy pillantást még egy példára, amely különféle referenciaobjektumokat tartalmaz.

ebben a kódban egy person változóval kezdjük, amely name, age és hobbiestulajdonságokat tartalmaz. Amikor ezt az objektumot kinyomtatjuk a konzolra, pontosan azt kapjuk, amire számítunk — ugyanazt az objektumot, amelyet éppen létrehoztunk.

ezután van egy changePerson nevű függvényünk, amely argumentumot vesz fel, néhány változtatást hajt végre, majd visszaad egy objektumot. Amikor létrehozzuk a thirdPerson változót, meghívjuk achangePerson függvényt azáltal, hogy átadjuk az eredeti person objektumot. Érdekes, hogy mi történik, ha a thirdPerson és person konzolra nyomtatunk.

figyeljük meg, hogy console.log(thirdPerson) visszatér egy teljesen új objektum új tulajdonságokkal. Most nézd meg, mi console.log(person) visszatér. Ez hasonló az eredeti objektumunkhoz, de új tulajdonságértékeket tartalmaz, amelyeket a changePerson függvényben vezettek be.

egyenlőség ellenőrzése

végül nézzük meg, hogyan viselkednek a primitív adattípusok és referenciaobjektumok az egyenlőség operátorokkal.

ha primitív adattípusokról van szó, nem számít, mi van a = jeltől jobbra, mindaddig, amíg az értékek megegyeznek. Ezt láthatjuk a a és b változókkal, amelyek másképp vannak írva, de ugyanazt az értéket értékelik ,ha a === – et használjuk, a szigorú egyenlőség operátort.

az ellenkezője igaz a második példában dog és cat. Bár úgy tűnhet, hogy azonos értékeket tartalmaznak, a egy tömb és egy referenciaobjektum, ami azt jelenti, hogy a === ellenőrzi, hogy mind a dog, mind a cat azonos hivatkozást tartalmaz-e a memóriában lévő értékre. Másrészt a bird === dog igaz, mert ugyanazt a referenciaobjektumot használják.

a kutya és a madár ugyanazt a hivatkozást használja, míg a macska annak ellenére nem, hogy azonos tömbje van

következtetés

és ezzel lezárjuk a bevezetésünket a pass by value vs pass by reference-be. Több téma is lefedhető ezen ernyő alatt alapvető, beleértve azt is, hogy mi történik, ha egy hivatkozást felülírnak vagy elvesznek, hogyan lehet másolni egy hivatkozást egy új objektum létrehozásához, és győződjön meg arról, hogy a másolat mély másolat, csak néhányat említve. Azt javaslom, hogy nézze meg az alább használt erőforrásokat, amelyek részletesebben foglalkoznak ezekkel a további témákkal.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.