Как да получите сцепление с референтна спрямо стойност в JavaScript

Тази статия разглежда как се държат различните типове данни на JavaScript, когато са присвоени на променлива. В зависимост от типа данни, паметта се разпределя по различен начин, за да се съхранява. Той може да запази ново пространство за съхранение на копие на стойността или може изобщо да не създаде копие и просто да посочи съществуващата стойност (референция).

Ето моите бележки, направени по време на курса Javascript30 от Уес Бос.

Числа, струнни и булеви

В JavaScript примитивните типове като неопределена, нулева, низ, число, булева и символ се предават по стойност.

нека име = „Марина“;
нека name2 = име;
console.log ({име, име2});
 >> {name: 'Marina', name2: 'Marina'}
name = „Виниций“;
console.log ({име, име2});
>> {name: 'Vinicius', name2: 'Marina'}
Предава се по стойност.

Когато името на променливата е присвоено, място в паметта с адрес 0x001 е запазено за съхранение на тази стойност. След това името на променливата сочи към този адрес. След това променливото name2 се задава на равно име. Ново пространство в паметта с нов адрес 0x002 е разпределено и съхранява копие на стойността, съхранена в адреса, на който посочва името.

Така че, когато искаме да променим стойността на името, стойността, съхранявана от name2, няма да бъде променена, тъй като нейното копие се съхранява на друго място.

Обекти и масиви

Обектите в JavaScript се предават чрез справка. Когато е зададена повече от една променлива, която да съхранява или обект, масив или функция, тези променливи ще сочат към същото разпределено пространство в паметта.

const animal = ['Cat', 'Dog', 'Horse', 'Snake'];
нека животните2 = животни;
console.log ({животни, животни2});
>>
{
  животни: [„Котка“, „Куче“, „Кон“, „Змия“],
  животни2: [„Котка“, „Куче“, „Кон“, „Змия“]
}
animal2 [3] = 'Уейл';
console.log (животни, животни2);
>>
{
  животни: [„Котка“, „Куче“, „Кон“, „Уел“],
  animal2: ['Cat', 'Dog', 'Horse', 'Wale']
}
Предаден чрез справка.

Когато животните са настроени да съхраняват масив, се разпределя памет и се свързва адрес към тази променлива. Тогава animal2 е настроен на равни животни. Тъй като животните съхраняват масив, вместо да създават копие на този масив и нов адрес в паметта, animal2 е просто насочен към същия обект на съществуващия адрес. По този начин всички промени, направени в животни2, ще се отразят на животните, тъй като те сочат към едно и също място.

Ще видите същото поведение и за обекти:

const лице = {
  име: „Марина“,
  възраст: 29 години
};
нека femme = човек;
femme.age = 18;
console.log ({person, femme});
>>
{
  лице: {име: 'Марина', възраст: 18},
  femme: {име: 'Марина', възраст: 18}
}

Копиране на обекти и масиви

Тъй като обикновено задание не е достатъчно за създаване на копие на обект, това може да се постигне с други подходи:

Масивите

парче ()

нека животните2 = животни.slice ();
animal2 [3] = 'Акула';

Concat ()

нека животните3 = [] .конка (животни);
animal3 [3] = 'Тигър';

спред (ES6)

нека animal4 = [... животни];
animal4 [3] = 'Лъв';

Промените ще засегнат само променения обект:

console.log ({животни, животни2, животни3, животни4});
>>
{
  животни: [„Котка“, „Куче“, „Кон“, „Змия“],
  животни2: [„Котка“, „Куче“, „Кон“, „Акула“],
  животни3: [„Котка“, „Куче“, „Кон“, „Тигър“],
  animal4: ['Cat', 'Dog', 'Horse', 'Lion']
}

обекти

присвоява ()

нека human = Object.assign ({}, лице, {възраст: 20});
console.log (човек, човек);
>>
{
  лице: {име: 'Марина', възраст: 29},
  човек: {име: 'Марина', възраст: 20}
}

Дълбок клонинг

Важно е да се отбележи, че тези методи са дълбоки само на едно ниво. За дълбоки клонинги има намръщен метод. Използвайте внимателно.

нека femme3 = JSON.parse (JSON.stringify (лице));
femme3.name = 'Лесли';
console.log (лице, femme3);
>>
{
  лице: {име: 'Марина', възраст: 29},
  femme3: {name: 'Leslie', възраст: 29}
}

Препратки

  • WesBos - Javascript 30
  • Вие не знаете JS: Обхват и затваряния от Кайл Симпсън

Първоначално публикуван на marina-ferreira.github.io.