Proslijediti po referenci ili vrijednosti

Vrijednosti u JavaScript-u su uvijek odredjenog tipa. Primitivni tip podataka su najsonovniji oblici vrijednosti (string, number, bigint, boolean, null, undefined, symbol) i oni se proslijede po vrijednosti / kopira se podatak.
Sa druge strane, svi objekti (kao obicni objekti, nizovi i funkcije) se proslijede po referenci / ne radi se o kopiji.
Sta to znaci?
Primitivni podaci se prosljedjuju po vrijednosti jer varijabla sadrzi sam podatak (kao broj ili tekst), dok se objekti prosljedjuju po referenci jer varijabla u sebi drzi referencu / adresu na kojoj se podatak nalazi.
let a = 7;
let b = a; // prosljedjivanje vrijednosti
b = b + 8; // b = 15; a = 7;
let c = {name: 'Jane'}; // kreiranje objekta
let d = c; // prosljedjivanje po referenci
d.lastName = 'Doe'; // objekat dobija novo svojstvo
console.log(c); // {name: 'Jane', lastName: 'Doe'}| Varijabla | Vrijednost | Adresa | Vrijednost | |
|---|---|---|---|---|
| a | 7 | / | 0x01 | {name: 'Jane', lastName: 'Doe'} |
| b | 15 | / | ||
| c | 0x01 | / | ||
| d | 0x01 | / |
Vazi i obrnuto. Izmjena c varijable bi promijenila d varijablu kako obe pokazuju na istu vrijednost.
Medjutim, treba imati na umu da prijenos po referenci znaci da:
let obj1 = {} // 0x01
let obj2 = {}; // 0x02
console.log(obj1 == obj2); // false
console.log({} == {}); // false
// ali
let obj3 = obj1; // 0x01
console.log(obj1 == obj3); // trueSvaki put kada kreiramo objekat, on je zaseban i cuva se na novoj adresi. Tako {} == {} je false jer nisu identicni objekti (0x01 =/= 0x02), dok obj1 == obj3 jesu jer imaju istu referencu (0x01).
let c = {}; // 0x01
let d = c; // 0x01
d.name = 'Jane'; // 0x01 dobija novo svojstvo
d = {author: 'Joe'}; // 0x02 definisan je novi objekat
console.log(c); // {name: 'Jane'}
console.log(d); // {author: 'Joe'}Znakom jednakosti je varijabli d dodijeljen objekat {} sa desne strane. c i d vise ne pokazuju na isti objekat i modifikovanje vrijednosti jedne varijable nece uticati na vrijednost druge.
| Varijabla | Vrijednost | Adresa | Vrijednost | |
|---|---|---|---|---|
| c | 0x01 | / | 0x01 | {name: 'Jane'} |
| d | 0x02 | / | 0x02 | {author: 'Joe'} |
Funkcija
Okolnosti u kojima se prijenos po vrijednosti i referenci jos primjenjuje je u funkcijama. Kroz argumente smo, u kodu ispod, funkciji proslijedili objekat i vrijednost 43.
let employee = {name: 'Jane'}; // 0x01
let a = 43;
function addAge(person, age) {
person.isOld = age;
// 0x01.isOld = 43;
}
addAge(employee, a); // 0x01, 43
console.log(employee); // {name: 'Jane', isOld: 43}- Objekat nije primitivni tip podatka i prenosi se po referenci, te mu je dodano svojstvo
isOldkroz adresu koja pokazuje gdje se nalazi objekat0x01u memoriji. - Sa druge strane, varijabla
agekoja sadrzi podatak primitivnog tipa nije proslijedjena kroz referencu, vec je kopirana u funkciju i postoji samo lokalno.
Sta ako varijabli person kojoj je proslijedjen objekat 0x01 dodijelimo novi objekat? Hoce li se globalni objekat employee promijeniti?
let employee = {name: 'Jane'}; // 0x01
let a = 43;
function addAge(person, age) {
person = {age: age};
// 0x02 = {age: 43};
}
addAge(employee, a); // 0x01, 43
console.log(employee); // {name: 'Jane'}person vise nema referencu na 0x01 i kroz tu varijablu ne mozemo izmjeniti employee objekat, samo lokalni person objekat na lokaciji 0x02.