Javascript —What are a pass-by value and a pass-by reference?
There are three important ways that you can manipulate a data value. First, you can copy it; for example, by assigning it to a new variable. Second, you can pass it as an argument to a function or method. Third, you can compare it with another value to see if the two values are equal.
- JavaScript: The Definitive Guide, 4th Edition.
나는 항상 새로운 개발 언어를 접할 때 위 3가지를 고려하고자 노력한다. 모든 개발 언어도 그렇듯이 Javascript 역시 예외일 수 없었고, Javascript로 개발해오면서 고민했던 pass-by value or pass-by reference의 개념을 정리하고자 한다.
Primitive type vs. Reference type
먼저 pass-by value or pass-by reference를 이해하기 위해서는 Javascript의 data type을 이해할 필요가 있다. Javascript에서 변수에 할당하는 data type은 크게undefined
, null
, boolean
, number
, string
, and symbol
과 같은 6가지 primitive type과 object
인 reference type 으로 나눌 수 있다.
당신이 하나의 변수에 값을 할당했을때, Javascript engine은 그 값이 primitive type 혹은 reference type인지를 판단할 것이다.
먼저, 변수에 primitive type이할당되었다면 변수에 할당된 실제 값에 접근할 수가 있다. 반면에 reference type은 실제 object가 아닌 object의 reference에 접근할 수 있다. (이 말을 이해하기 위해서는 먼저 Javascript가 객체지향이며 MDN에서 정의하고 있는 prototype에 대한 선지식이 필요하다.)
여기서 Primitive type으로 선언된 변수가 또다른 변수에 할당하게 되었을 경우 새 변수에는 copy된 값이 전달된다는 것이다.
예제를 살펴보자.
var apple = 2;
apple이라는 변수안에 2라는 primitive type(number)이 선언되었다.
var banana = apple;
이때 또다른 변수 banana에 할당시켰을 경우 Javascript engine은 apple안에 있는 값을 copy하여 banana에 붙여넣기를 한다.
banana = 5;
그리고 다시 banana에 5를 할당하게 되면 banana의 변화와 상관없이 apple은 여전히 2라는 것을 알 것이다.
reference type의 경우도 하나의 변수에서 또다른 변수로 할당이 되는 경우 copy로 접근하게 되지만 primitive와 차이점은 heap memory에 올라가 있는 object의 주소가 copy된다는 것이다. 다음 예제를 보면 이해가 더 쉬울 것이다.
var a = { name: 'Kim' };
변수 a에 property(속성)를 name
이라하고 value를 Kim
이라는 object를 선언하였다. 이때 object 는 heap이라는 메모리 어딘가에 빈 객체로 생성이 된 상태에서 name: ‘Kim'
이라는 정보가 저장되었을 것이다.
이때, 새 변수 b를 선언하여 a 를 할당하게 된다면 a와 b는 heap에 올라가 있는 같은 object를 가리킬 것이다.
var b = a;
이때, 값을 수정해 보면 둘 다 가리키는 object가 같으므로 b역시 수정이 이루어 진다는 것을 알수 있다.
b.name = 'Lee';
console.log(b); // { name: 'Lee' }
console.log(a); // { name: 'Lee' }
console.log(a.name); // 'Lee'
Passing by value vs Passing by reference
위 예제를 이해했다면, 개인적으로 판단컨데 passing by value 와 passing by reference를 50%이상은 이해한 것이라 볼 수 있다. Javascript는 모든 function arguments들은 항상 passing by value이다. 이 말은 function 안에 들어온 argument의 값을 아무리 변경시킨다 할 지라도 function 외부에 변수에 영향을 주지 않는다는 것이다.
function sphere(r) {
r = r * r * PI
}var a = 10;
sphere(a);
console.log(a); // a = 10;
여기서 더 우리가 명백하게 결정내릴 수 있는 것은 primitive type은 passing by value라는 것이다. 하지만 reference type의 경우는 다르다.
function makedWheel(transportation) {
transportation.wheel = 4;
}var car = {
wheel: 0
}makedWheel(car);
console.log(car.wheel); // 4;
앞에서 언급한 reference type 에 대한 이해가 되었다면 이 예제 역시 왜 primitive타입과 다른 결과가 나왔는지 알 수 있을 것이다.
여기서 주의해야하는 점은 무조건 reference type (Object)를 넘긴다고 해서전부 passing by reference인 것은 아니다.
function makedWheel2(transportation) {
transportation = {
wheel: 4
};
}var car = {
wheel: 0
}makedWheel2(car);
console.log(car.wheel); // 0
이는 함수 makedWheel2 내부 scope에 transportation는 또 다른 Object를 가리키게 됨으로 외부에 선언된 car라는 변수에 영향이 가지 않기 때문이다.
To summarize
- Javascript data type은 primitive type & reference type 2종류로 나뉜다.
- 기본적으로 Javascript에서는 passing by value를 가진다.
- primitive type : passing by value / reference type : passing by reference
이상 Javascript passing by value or reference 에 대한 정리를 해보았다. 관련 질문 및 피드백 언제든 환영입니다.
-Nicegirl-