
У цій статті розглядається поведінка різних типів даних JavaScript, коли вони присвоюються змінній. Залежно від типу даних пам’ять виділяється для зберігання по-різному. Він може зарезервувати новий простір для зберігання копії значення, а може взагалі не створити копію і просто вказати на існуюче значення (посилання).
Ось мої нотатки, зроблені під час проходження курсу Javascript30 Весом Босом.
Числа, рядки та булеві значення
В 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';
concat ()
let animals3 = [].concat(animals);animals3[3] = 'Tiger';
розповсюдження (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 }}
Глибокий клон
Важливо зазначити, що ці методи глибиною лише один рівень. Для глибоких клонів існує метод, який не відповідає вимогам. Використовуйте обережно.
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: Сфера застосування та закриття Кайла Сімпсона
Спочатку опубліковано на marina-ferreira.github.io.