[javascript] call by value, call by reference

daewoong·2021년 10월 25일

설명

프로젝트를 하던 중 자바스크립트의 호출에 대한 궁금증이 생겼고 공부해보기로 했다.
예시코드를 먼저 작성해보겠다.

let number = 3;
let obj = {
 number: 3 
}

function change(primitive, object) {
  primitive = 5;
  object.number = 5;
}

change(number, obj);
console.log(number);      // 3
console.log(obj.number);  // 5

number는 변하지 않았고 obj는 변했다. 원시타입인 number는 "값에 의한 전달"이 된 것 같고 참조타입인 obj는 "참조에 의한 전달"이 된 것 같다. 하지만 모던 자바스크립트 Deep dive 책을 보면 이런 내용이 나온다.

"값에 의한 전달"과 "참조에 의한 전달"은 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서 동일하다. 다만 식별자가 기억하는 메모리 공간, 즉 변수에 저장되어 있는 값이 원시 값이냐 참조 값이냐의 차이만 있을 뿐이다. 따라서 자바스크립트에서는 "참조에 의한 전달"은 존재하지 않고 "값에 의한 전달"만이 존재한다고 말할 수 있다.

이해한 내용을 작성해보자.

  • 원시타입
let number = 100;
function change(copy) {
 copy = 200; 
}

change(number);
console.log(number) // 100
  1. change함수를 사용하는 부분에서 number의 값이 전달돼서 copy에 100이라는 값이 할당된다.
  2. 자바스크립트에서 원시타입은 변경 불가능한 값(immutable value)이기 때문에 새로운 공간을 할당해 200을 넣고 copy가 새로운 곳을 가르키도록 한다.
  • 참조타입
let obj = {
  number: 100
};
function change(copy) {
 copy.number = 200;
}

change(obj);
console.log(obj.number) // 200
  1. change함수를 사용하는 부분에서 obj에 저장되어있는 참조값이 copy에 할당된다.
  2. 참조 타입은 변경 가능한 값(mutable value)이기 때문에 copy가 직접 0x005에 저장되어 있는 객체를 변경한다.
  • 추가 내용
let obj = {
  number: 100
};
function change(copy) {
 copy = {
   number: 200
 }
}

change(obj);
console.log(obj.number) // 100


위 내용과 그림들을 참고하면 추가내용이 왜 저렇게 되는지 알 수 있다.

결론

함수 내에서 파라미터로 받은 객체의 속성 값을 변경할 수는 있지만 그렇게되면 원본이 훼손되어 어떤 코드에서 변경되었는지 추적하기 어렵기 때문에 직접 변경하는 것은 안좋은 코딩방법이라고 한다. 이부분을 숙지해서 객체의 불변성을 지키자.

profile
잘하자

0개의 댓글