Pass by Value vs Pass By Reference in JavaScript

jos olet uusi JavaScript, mahdollisuudet ovat olet jo törmännyt joitakin hauska käyttäytyminen tämä kieli on tarjota (todistuskappale A). Aluksi nämä oudot omituisuudet saattavat tuntua naurettavilta ja turhauttavilta, mutta lupaan, että kaiken tuon hulluuden takana on metodi.

yksi vaikeimmista ylitettävistä esteistä on nöyrän mielipiteeni mukaan se ero, että ohitetaan arvo ja ohitetaan viite. Miksi tämä konsepti on niin hankala? Alkajaisiksi, voit varmasti saada melko pitkälle ilman todella ymmärtää, miten JavaScript vuorovaikutuksessa alkeellisia arvoja ja viitearvoja. Tämä voi, ja useammin kuin ei, johtaa ton vikoja, joita on vaikea jäljittää ja ärsyttävää korjata. Toiseksi, tämä on käsite, joka tulee esiin teknisissä haastatteluissa, joten sen ymmärtämättä jättäminen lasketaan valtavaksi punalipuksi sinua vastaan.

älä pelkää, lukijatoveri! Alkakoon koulutus …

primitiiviset tietotyypit

Javascriptissä voidaan jakaa tietotyypit kahteen eri ämpäriin, primitiivisiin tietotyyppeihin ja objekteihin.

alkukantaisia tietotyyppejä eli arvoja ja oliotyyppejä tai viitearvoja kuvaava kaavio

Javascriptissä on kuusi alkeellista tietotyyppiä: string, number, boolean, undefined, null, ja symbol ES6: sta lähtien.

alkeelliset tietotyypit kulkevat eli kopioivat arvon mukaan ja ovat muuttumattomia, eli olemassa olevaa arvoa ei voi muuttaa samalla tavalla kuin jokin array tai olio voi. Katsotaanpa katsomaan koodi alla nähdä tämän toiminnassa.

luotu käyttäen jsbin.com

tässä on luotu kaksi muuttujaa, x = 10 ja y = x. Koska 10 on luku ja alkeisarvo, kun asetamme y = x, kopioimme arvon itse asiassa, eli 10, ja määritämme sen arvoon y. Voimme myös visualisoida tämän alla olevan taulukon avulla.

jos muuttaisimme arvon x, huomaisimme, että y säilyttää arvonsa 10. Tämäkin johtuu siitä, että primitiiviset arvot kopioidaan, joten y’s arvo on riippumaton x’s arvosta. Ajattele sitä valokopiona kuvasta. Kun olet tehnyt kopion, sinulla on kaksi samanlaista kuvaa: Alkuperäinen ja kopio. Jos alkuperäinen leikattaisiin kahtia, vain alkuperäinen muuttuisi ja faksikuva pysyisi täsmälleen samana.

ylikirjoitamme X: n arvon, mutta y pysyy samana

Referenssioliot

oliot sen sijaan siirtyvät referenssin ja pisteen avulla johonkin muistiin merkittyyn paikkaan, ei itse arvoon. Katsotaanpa tätä koodistamme.

muuttujat x ja y viittaavat nyt olioihin eikä primitiivisiin tietotyyppeihin

tässä esimerkissä x on nyt olio, joka osoittaa {dog: "poodle"}. Kun luomme muuttujan y ja annamme sille arvon x, voimme nyt hyödyntää eri ominaisuuksia x, joka sisältää arvon dog, eli "poodle". Tämä tuntuu täsmälleen sama logiikka käytetään primitiivisiä arvoja, mutta katsotaanpa katsomaan meidän kätevä-dandy kaavion alla nähdä hienovarainen, mutta tärkeä ero.

sekä x että y viittaavat muistiin (keksittyyn) osoitteeseen, joka tallentaa viittauksen kohteeseen

nyt tämä kaavio näyttää hieman erilaiselta kuin silloin, kun muuttujillamme x ja y oli alkeellisia tietotyyppejä. Tässä versiossa huomaamme, että sekä x että y arvot eivät ole tietotyyppejä, vaan viittauksia muistissa olevaan osoitteeseen, itse asiassa samaan osoitteeseen! Nyt katsotaan, mitä tapahtuu x: lle, jos lisäämme size: n uuden ominaisuuden y

x edelleen palauttaa esineen,mutta nyt sillä on myös lisäominaisuus size! Jälleen tämä johtuu siitä, että sekä x että y viittaavat samaan referenssikohteeseen, joten yhteen muuttujaan tehdyt muutokset näkyvät toisessa.

kaavio havainnollistaa, miten y: n muutos päivittää viitearvon, joka on jaettu X: n kanssa

auttaakseen minua muistamaan tämän käsitteen, haluan ajatella viitearvoja talona ja muuttujia ihmisinä, jotka asuvat kyseisessä talossa. Kaikki asukkaat (muuttujat) voivat sanoa ”Minulla on talo” ja osoittaa samaa taloa. Jos yksittäinen asukas päättää, että haluaa maalata talon keltaiseksi, niin kaikilla asukkailla on nyt keltainen talo, koska se on jaettu.

katsotaanpa vielä yhtä esimerkkiä, joka sisältää erilaisia referenssikohteita.

tässä koodissa lähdetään liikkeelle muuttujasta person, joka sisältää ominaisuudet name, age ja hobbies. Kun tulostamme tämän objektin konsoliin, saamme juuri sen, mitä odotamme — saman objektin, jonka juuri loimme.

seuraavaksi on funktio changePerson, joka ottaa argumentin, tekee muutaman muutoksen ja palauttaa sitten objektin. Kun luomme muuttujan thirdPerson, vedotaan funktioonchangePerson siirtämällä siihen alkuperäinen oliomme person. Mielenkiintoista on, mitä tapahtuu, kun tulostamme konsolille thirdPerson ja person uudelleen.

huomaa, että console.log(thirdPerson) palauttaa kokonaan uuden objektin uusilla ominaisuuksilla. Katso nyt, mitä console.log(person) palaa. Tämä on samanlainen kuin alkuperäinen kohteemme, mutta se sisältää uusia ominaisarvoja, jotka otettiin käyttöön changePerson funktiossamme.

tasa-arvon tarkistaminen

lopuksi katsotaan, miten alkeelliset tietotyypit ja referenssiobjektit käyttäytyvät tasa-arvo-operaattoreiden kanssa.

primitiivisten tietotyyppien kohdalla = – merkin oikealla puolella ei ole väliä, kunhan arvot ovat samat. Tämä voidaan nähdä yllä muuttujilla a ja b , jotka kirjoitetaan eri tavalla, mutta arvioidaan samaan arvoon, kun käytetään ===, tiukkaa tasa-arvo-operaattoria.

toisessa esimerkissä tilanne on päinvastainen dog ja cat. Vaikka voi näyttää siltä, että ne sisältävät identtiset arvot, on array ja viite-objekti, mikä tarkoittaa, että === tarkistaa, onko sekä dog että cat sama viittaus arvoon muistissa. Toisaalta bird === dog pitää paikkansa, koska niillä on sama referenssikohde.

koira ja lintu jakavat saman referenssin, kun taas kissa ei siitä huolimatta, että niillä on identtinen ryhmä

johtopäätös

ja tämä päättää johdantomme pass by value vs pass by reference. On enemmän aiheita, jotka voidaan kattaa tämän sateenvarjon perustavanlaatuinen, mukaan lukien mitä tapahtuu, kun viittaus on ylikirjoitettu tai kadonnut, miten kopioida viittaus luoda uusi objekti ja varmista, että kopio on syvä kopio, vain muutamia mainitakseni. Suosittelen tarkkailun resursseja käytin alla, jotka eivät mennä joitakin näistä lisäaiheista yksityiskohtaisemmin.

Vastaa

Sähköpostiosoitettasi ei julkaista.