assign() 과 객체의 참조값, 참조에 의한 전달
온라인 강의를 병행하던 중 Object.assign()
함수에 대한 예문을 연습하고 있었는데 의아한 점이 있었고 의문점을 해결하면서 확실하게 알게된 객체의 특성중 참조값의 개념에 대해서 작성하여 남기고자 한다.
Object.assgin(target, ...sources)
의 개념은 대상 객체인 target
에 출처 객체sources
의 열거 가능한 자체 속성들을 복사하여 붙여넣은 후 대상 객체를 반환하는 메소드이며, target
이 빈객체{}
가 아닐 경우, 반환받은 값을 저장한 새로운 변수는 target
과 참조값을 공유한다.
여기서 MDN의 내용에서의 기본개념에대한 설명과 달리 내가 추가한 내용은 target
과 참조값을 공유한다 라는 것이다. MDN문서에도 참조값을 복사한다라고 명시되어 있으며, 객체의 특성에 의한 현상으로 객체의 참조값과 참조에 의한 전달이 무엇인지 정확하게 예제로 활용하기에 적합했다고 생각한다.
예제는 다음과 같다.
// Object.assign()
var userAge = {
name : 'Lee',
age : 25
}
var userEmail = {
name : 'Lee',
email : 'dankthedust@gmail.com'
}
var target = Object.assign(userAge, userEmail);
console.log(target)
console.log(userAge)
console.log(target === userAge) // true
//같은 참조값을 공유하는 지 확인을 위해서 userAge에 다른 값으로 변경하고 target을 확인해보자
const a = {name : 'Lee'};
const b = {name : 'Lee'};
console.log(a);
console.log(b);
console.log(a===b); // false
// 위의 target과 userAge도 같은 객체값을 가지고 있고 a와b도 같은 객체 값을 가지고 있는 것처럼 보이는데 일치연산자의 결과는 서로 다를까?
// 새로운 주소를 가진 객체 데이터를 만들면서 assign()을 사용하는 방법은 새로운 객체 데이터에 userAge와 userEmail을 담아 새로운 변수에 저장하면 된다.
// const target = Object.assign(userAge, userEmail);을 다음과 같이 변경한다
const newTarget = Object.assign({}, userAge, userEmail);
console.log(target === newTarget); // false
위의 console.log(target)
과 console.log(userAge)
의 결과는
{
name : 'Lee',
email : 'dankthedust@gmail.com'
}
으로 같으며, Object.assign()
은 변수 userAge
와 userEmail
을 병합한 결과를 나타낸다.
그런데 변수 a와b 또한 console.log(a)
, console.log(b)
를 하면 출력되는 값은 동일하게 나오는 것을 볼 수 있다.
그런데 어째서 일치연산자의 결과는 서로 다른 것일까?
그 이유는 객체를 할당한 변수에는 생성된 객체가 실제로 저장된 메모리 공간의 주소, 즉 참조값이 저장되기 때문이다.
객체는 원시값과 다르게 변경 가능한 값인데, 변경이 가능한 이유가 위와 같은 이유에서 나온다.
Object.assign()
을 통해 나온 결과물을 target
에 전달하였고 이는 실제 객체가 저장된 메모리 공간의 주소인 참조값이 전달된 것이고
이를 모던자바스크립트에선 참조에 의한 전달 이라고 표현하고 있다.
그럼 이를 확인하기 위해 userAge
의 객체값을 갱신하여 target또한 그 값이 같이 갱신되는 지 확인해 보자.
userAge.address = 'Seoul';
console.log(target);
console.log(userAge);
console.log(target === userAge); // true
객체는 값에 의한 전달이 아닌 참조에 의한 값이 전달 된다.target
과 userAge
는 같은 메모리 주소를 값으로 갖는 변수이기 때문에 target
의 객체값이 변경되었을 때 그 값을 공유한다.
따라서 일치연산자의 결과가 true
값이 나온 것이다.
변수 a
와 b
가 다른 이유는 console.log()
를 통한 값은 같아 보여도 실제 그 값이 저장된 메모리는 각각 다르다는 것을 말한다.
즉 a
, b
는 다른 참조값을 가지고 있어 각각 다른 메모리에 동일한 값이 저장되어 있어 일치연산자의 결과가 false이지만
같은 참조값을 가지는 target과 userAge는 true의 결과가 나오게 되며, userAge에 새롭게 다른 객체 값을 할당하는 것이 아닌 갱신을 할 시에는 그 영향이 target에도 동일시 된다라는 의미이다.
"정리하자면"
일치 연산자를 통해 비교한 결과가 target
과 userAge
는 true
,a
와 b
는 false
처럼 객체 값이 같음에도 둘의 결과가 다른 이유는 자바스크립트에서 객체는 값을 저장하는 것이 아닌 값을 저장하고 있는 메모리의 주소를 값으로 갖는다.
즉, Object.assign을 통한 결과 값을 담은 target
은 userAge
와 같은 주소를 참조하는 값을 가졌다는 것을 알 수 있고,a
와 b
는 메모리에 담긴 값은 일치하는 것 같아도 각각 다른 메모리 참조값을 저장했으며, 다른 메모리에 저장된 값이라는 것을 의미한다.