
모던 자바스크립트 deep dive를 공부하다가 원시 값과 객체 비교 파트에서 값에 의한 전달, 참조에 의한 전달, 공유에 의한 전달이라는 개념이 나왔다.
세 개념 모두 ECMAScript의 용어는 아니고 다른 프로그래밍 언어에서 사용되는 용어라고 하여 이 개념이 무엇인지 좀 더 찾아보았다.
예시 코드:
function multiplyByTwo(value) {
value = value * 2;
console.log("Inside function:", value);
}
let number = 3;
multiplyByTwo(number);
console.log("Outside function:", number);
출력 결과:
Inside function: 6
Outside function: 3
코드의 흐름도:
1. multiplyByTwo 함수에 number라는 값 3이 전달됨.
2. 함수 내부에서 value는 2배가 되어 6이 됨.
3. 함수 외부에서 number는 여전히 3.
=> 원시 값은 변경 불가능한 값이기 때문이라고 볼 수 있겠다. 따라서 함수 내부의 value와 함수 외부에 선언된 number는 각각 다른 메모리 주소를 참조하기 때문에 변수 내부에서 값의 수정이 일어나도 식별자가 다르기 때문에 다른 값을 가지게 된다.
예시 코드:
function addToProperty(obj) {
obj.property = obj.property + 5;
console.log("Inside function:", obj.property);
}
let myObject = { property: 10 };
addToProperty(myObject);
console.log("Outside function:", myObject.property);
출력 결과:
Inside function: 15
Outside function: 15
코드의 흐름도:
1. addToProperty 함수에 myObject라는 객체가 전달됨.
2. 함수 내부에서 객체의 property에 5가 더해져 15가 됨.
3. 함수 외부에서 myObject의 property는 15.
=> 원시 값을 가지는 변수와는 다르게, 변수에 객체를 저장하면 변수는 '참조값'을 가지게 된다.
참조값이란 C나 C++에서 사용하는 포인터와 비슷한 개념으로 실제 객체 값이 저장되어 있는 메모리 주소를 가리키는 것을 말한다. 즉, myObj라는 변수에 { name: 'popo' }라는 객체를 저장한다면, myObj에는 0x003이라는 { name: 'popo' } 객체 값이 저장된 메모리 주소가 저장되고, myObj를 참조하면 메모리 주소 0x003가 참조되어 0x003에 저장되어 있는 { name: 'popo' }가 불러와지는 것.
let myObj1 = { name : 'popo' };
let myObj2 = myObj1;
myObj2.age = 25;
console.log(myObj1); // { name: 'popo', age: 25 }
console.log(myObj2); // { name: 'popo', age: 25 }
즉, 같은 메모리 주소(객체가 저장된 곳을 가리킴)를 참조하고 있기 때문에 함수 내부에서나 다른 변수에서 생성, 제거, 수정 등 변화가 일어나면 원본에도 변화가 일어나는 것이다.
예시 코드:
function changeName(person) {
person = { name: "Alice" };
console.log("Inside function:", person.name);
}
let user = { name: "Bob" };
changeName(user);
console.log("Outside function:", user.name);
출력 결과:
Inside function: Alice
Outside function: Bob
코드 흐름도:
1. changeName 함수에 user라는 객체가 전달됨.
2. 함수 내부에서 person에 새로운 객체가 할당되지만, 이는 함수 외부의 user와는 독립적임.
3. 함수 외부에서 user의 name은 여전히 "Bob".