Call by Value vs Call by Reference

메론맛캔디·2021년 10월 16일
0

기술면접

목록 보기
2/30

변수, 함수등에 인자가 대입될 때, 인자를 어떤 방식으로 넘겨줄까?

Call by Value

  • 함수 호출 시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
  • 같은 값을 가진 데이터가(복사된 값이) 메모리에 또 하나 만들어져서 저장된다.
  • primitive(원시)타입 데이터는 메모리에서 주소값을 거치지 않고 바로 데이터를 보관한다.
let num = 10;
function modifyNum() {
  num = 20;
  return num;
}

console.log(modifyNum(num)); // 20
console.log(num); // 10

reference가 아닌 value로 전달되기 때문에 변경사항들은 함수 외부에서 발생하는 변수와 분리되고, 값을 변경해도 원본 값의 실제 참조는 변경되지 않는다.


Call by Reference

  • 함수 호출 시 해당 reference(메모리 주소를 담고있는 변수, 값에 대한 참조 주소)를 넘겨준다.
  • 값이 복사되는 것이 아니라, 메모리의 주소값을 담는다.
  • object, array들과 같은 원시타입이 아닌 유형(non-primitive data type)의 변수를 함수의 매개변수로 전달될 경우 원래 변수의 참조(reference)가 업데이트 된다.
let num = {first : 10};
function modifyNum() {
  return num.first = 20;
}

console.log(modifyNum(num)); // 20
console.log(num); // 20

modifyNum 함수의 argument에 num을 전달하면 함수 외부 num의 참조값이 전달된다. 따라서 함수 내에서 num.first를 변경하면 외부의 값도 같이 바뀐다.



Primitive type 원시타입

  • immutable value이다. 변경 불가능한 값이다.
  • 변수에 실제 값이 저장된다.
  • 다른 변수에 할당하면 원시 값이 복사되어 전달된다. pass by value. 사실 엄격하게 표현하면 변수에 값이 전달되는 것이 아니라 메모리 주소가 전달된다. 왜냐하면 변수네이밍(식별자)는 값이 아니라 메모리 주소를 기억하기 때문이다.

Object / Reference type 객체 타입

  • mutable value이다. 변경 가능한 값이다.
  • 변수에 참조 값(reference)이 저장된다.
  • 다른 변수에 할당하면 원본의 참조 값(reference)이 복사되어서 전달된다. pass by reference

객체를 생성하고 관리하는 방식은 복잡하며 비용이 많이드는 일이다. 왜냐하면 객체는 원시값처럼 크기가 일정하지도 않기 때문이다. 따라서 프로퍼티 값이 객체일 수도 있어서 deep copy 해서 생성하는 것은 비용이 많이 드는 일이며, 메모리 효율에 좋지 않다.

shallow copy 얕은 복사

  • 한 단계까지만 복사하는 것
  • spread 연산자
const example = {x : {y: 1}};
const example2 = {...example};
example.x === example2.x // true
example === example2 // false
  • 객체를 다른 변수에 할당하는 것
const example = {x : {y: 1}};
const example2 = example; 
example === example2 // true

deep copy 깊은 복사

  • 중첩 객체까지 모두 복사하는 것
  • lodash의 cloneDeep
  • 원시 값을 다른 변수에 할당하는 것
const example = 3
const example2 = example;
example === example2 // true


정리

  • call by value - 원시타입, 값이 복사되어서 전달
  • call by reference - 참조타입, 메모리 주소 값이 복사되어서 전달


추가

값에 의한 전달 (pass by value)와 참조에 의한 전달(pass by reference)는 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서 동일하다.
하지만 pass by reference는 두 개의 식별자가 하나의 객체를 공유하는 것에 더 가깝다. 왜냐하면 자바스크립트에는 포인터가 존재 하지 않기 때문에 자바스크립트에는 pass by reference가 존재하지 않고, pass by value만 있다고 볼 수 있다.

출처 : 자바스크립트 Deep Dive

0개의 댓글