Πώς να πάρετε μια ιδέα για την αναφορά έναντι της τιμής στο JavaScript

Αυτό το άρθρο περιγράφει τον τρόπο συμπεριφοράς των διαφόρων τύπων δεδομένων JavaScript όταν έχουν αντιστοιχιστεί σε μια μεταβλητή. Ανάλογα με τον τύπο δεδομένων, η μνήμη κατανέμεται διαφορετικά για την αποθήκευσή της. Μπορεί να δεσμεύσει έναν νέο χώρο για να αποθηκεύσει ένα αντίγραφο της τιμής ή μπορεί να μην δημιουργήσει ένα αντίγραφο καθόλου και απλά να δείξει την υπάρχουσα τιμή (αναφορά).

Ακολουθούν οι σημειώσεις μου που ακολούθησαν το μάθημα Javascript30 του Wes Bos

Αριθμοί, χορδές και Booleans

Σε JavaScript, πρωτόγονων τύπων όπως undefined, null, string, number, booleanκαι symbolέχουν περάσει από την αξία.

let name = ‘Marina’;let name2 = name;
console.log({name, name2}); >> { name: ‘Marina’, name2: ‘Marina’ }
name = ‘Vinicius’;
console.log({name, name2});>> { name: ‘Vinicius’, name2: ‘Marina’ }

Όταν nameεκχωρηθεί η μεταβλητή, δεσμεύεται ένα κενό στη μνήμη με διεύθυνση του 0x001για να αποθηκεύσει αυτήν την τιμή. Στη nameσυνέχεια, η μεταβλητή δείχνει αυτήν τη διεύθυνση. Η μεταβλητή name2ρυθμίζεται έπειτα στο ίδιο name. Ένας νέος χώρος στη μνήμη, με μια νέα διεύθυνση 0x002εκχωρείται και αποθηκεύει ένα αντίγραφο της τιμής που είναι αποθηκευμένη στη διεύθυνση στα nameσημεία.

Έτσι, όποτε θέλουμε να τροποποιήσουμε την τιμή name, η τιμή που αποθηκεύεται από name2δεν θα αλλάξει, δεδομένου ότι είναι αντίγραφο, αποθηκευμένη σε διαφορετική τοποθεσία.

Αντικείμενα και πίνακες

Τα αντικείμενα σε JavaScript περνούν με αναφορά. Όταν περισσότερες από μία μεταβλητές έχουν ρυθμιστεί για αποθήκευση είτε ενός object, arrayείτε function, αυτές οι μεταβλητές θα δείχνουν στον ίδιο εκχωρημένο χώρο στη μνήμη.

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']}

Όταν animalsέχει ρυθμιστεί να αποθηκεύει έναν πίνακα, εκχωρείται μνήμη και μια διεύθυνση συσχετίζεται με αυτήν τη μεταβλητή. Στη συνέχεια animals2ορίζεται στο ίδιο animals. Δεδομένου ότι animalsαποθηκεύει έναν πίνακα, αντί να δημιουργεί ένα αντίγραφο αυτού του πίνακα και μια νέα διεύθυνση στη μνήμη, animals2απλώς επισημαίνεται στο ίδιο αντικείμενο στην υπάρχουσα διεύθυνση. Με αυτόν τον τρόπο τυχόν αλλαγές που γίνονται animals2θα προβληματιστούν animals, επειδή δείχνουν στην ίδια τοποθεσία.

Θα δείτε την ίδια συμπεριφορά για αντικείμενα:

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 }}

Αντιγραφή αντικειμένων και συστοιχιών

Δεδομένου ότι μια απλή ανάθεση δεν αρκεί για την παραγωγή αντιγράφου ενός αντικειμένου, αυτό μπορεί να επιτευχθεί με άλλες προσεγγίσεις:

Πίνακες

φέτα()

let animals2 = animals.slice();animals2[3] = 'Shark';

συμπυκνωμένος ()

let animals3 = [].concat(animals);animals3[3] = 'Tiger';

spread (ES6)

let animals4 = [...animals];animals4[3] = 'Lion';

Οι αλλαγές θα επηρεάσουν μόνο το αντικείμενο που τροποποιήθηκε:

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']}

Αντικείμενα

αναθέτω()

let human = Object.assign({}, person, { age: 20 });
console.log(person, human);>>{ person: { name: 'Marina', age: 29 }, human: { name: 'Marina', age: 20 }}

Βαθιά κλώνος

Είναι σημαντικό να σημειωθεί ότι αυτές οι μέθοδοι έχουν βάθος μόνο ενός επιπέδου. Για βαθιά κλώνους υπάρχει μια μέθοδος frown on. Χρησιμοποιήστε προσεκτικά.

let femme3 = JSON.parse(JSON.stringify(person));femme3.name = 'Leslie';
console.log(person, femme3);>>{ person: { name: 'Marina', age: 29 }, femme3: { name: 'Leslie', age: 29 }}

βιβλιογραφικές αναφορές

  • WesBos - Javascript 30
  • Δεν ξέρετε JS: Scope & Closures από τον Kyle Simpson

Αρχικά δημοσιεύθηκε στο marina-ferreira.github.io.