Javascript —What are a pass-by value and a pass-by reference?

for beginners

image ref. https://www.youtube.com/watch?v=JUXQL02PLlE
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 typeobjectreference 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-

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.