일단 본론에 들어가기 앞서 아래 코드 결과를 예측해보자.
const person = { name: "Lydia", age: 21 };
const changeAge = (x = { ...person }) => x.age += 1;
const changeAgeAndName = (x = { ...person }) => {
x.age += 1
x.name = "Sarah"
};
changeAge(person);
changeAgeAndName();
console.log(person);
결과부터 말하면 위 코드의 결과는 { name: “Lydia”, age: 22 }
가 된다.
왜 이런 결과가 나왔을까?
자바스크립트에서 함수의 인자를 넘길 때, 인자는 값에 의한 전달(pass by value)
방식으로 처리된다. 이는 인자의 값이 복사되어 함수 내부로 전달되는 것을 의미한다. 이 때 복사하는 방식은 얕은 복사와 같이 처리된다.
코드의 전반적인 흐름은 객체 타입의 value를 업데이트 시키는 코드이다.
value를 업데이트 시키기 위한 함수로 changeAge
, changeAgeAndName
를 선언해서 사용하고 있는데 이 때 두 함수의 차이점은 호출문에서 인자 전달의 유무에서 차이점이 있다. 두 함수의 파라미터인 x식별자에 값이 할당되는 방식은 아래와 같이 할당된다.
changeAge
: 인자로 전달 된 객체의 값을 복사하지만 참조 타입의 값을 복사하기 때문에 결국 같은 참조를 가리키게 된다. 즉 x의 값이 할당되는 방식은 const x = person
와 같이 동작하게 된다.changeAgeAndName
: person 변수의 값 자체를 Spread로 복사하기 때문에 콜스택에서 x와 person은 서로 다른 메모리힙의 주소를 가리키고 있고 메모리힙에서의 메모리 value는 동일한 상태가 된다. 즉 x의 값이 할당되는 방식은 const x = { name: "Lydia", age: 21 }
과 같이 동작하게 된다.