자바스크립트의 자료형은 크게 두 가지로 분류를 할 수 있습니다.
1. Primitive Type
2. Reference Type
1번은 문자, 숫자 등의 자료를 의미합니다. 이 자료형은 변수에 자료가 곧바로 저장이 됩니다.
const name = 'john';
const age = 20;
john, 20 이라는 값이 왼쪽의 name, age 변수에 곧바로 저장이 됩니다. 그래서 이런 일이 가능합니다.
let name1 = '김';
let name2 = name1;
name1 = '박';
console.log(name1); // 박
console.log(name2); // 김
name1 이라는 변수에 값을 넣고 name2에는 그 변수를 복사해서 넣었습니다. 그리고 name1 변수의 값을 변경했습니다. 그리고나서 name1과 name2를 출력하면 어떤 결과가 나올까요? name1은 변경을 했으니 변경한 값인 '박'이 나오고 name2에는 복사했던 값인 '김'이 나옵니다. 서류 원본을 복사하고나서 원본을 수정한다고 해서 복사본까지 자동으로 바뀌지 않는 것이라고 이해하시면 됩니다.
2번 Reference Type은 1번과는 조금 다르게 작동을 합니다. array나 object 같은 reference type은 값이 변수에 바로 저장이 되지 않습니다. Reference Type은 변수에 자료가 저장되는 것이 아니라 reference라는 것이 저장됩니다.
const 사람 = { name : 'Kim' };
이 때 사람이라는 변수에 저장되는 것은 obj 그 자체가 아니라 obj가 '어디어디에 저장되어있다!' 를 가리키는 일종의 '화살표'가 저장되는 것입니다. 이 때 어디어디는 컴퓨터 내의 메모리를 의미합니다. Reference Type의 이러한 특성으로 인해 다음의 세 가지 경우 같은 독특한 현상이 발생합니다.
1️⃣ 복사를 했을 때 값이 공유됩니다. (정확히 말하면 Reference가 공유가 되는 것이죠)
let name1 = { name : '김' };
let name2 = name1;
name1.name = '박';
console.log(name1.name); // 박
console.log(name2.name); // 박
name1에 obj를 할당했고 name2에는 name1을 복사해서 넣었습니다. 그리고 name1의 name이라는 key의 value를 '박'으로 수정해줬습니다. 그리고 name1.name과 name2.name을 출력해봤습니다.
결과를 보면 둘 다 '박'이 나옵니다. name2의 값은 수정해주지 않았음에도 불구하고 말입니다. 이런 일이 발생하는 것은 reference 때문입니다. object나 array같은 reference type 자료형은 복사를 했을 때 값을 복사해서 넣는 것이 아니라 reference을 복사해서 넣기 때문에, 위 코드에서 name1과 name2는 같은 곳을 가리키고 있는 화살표를 공유하고 있는 것을 의미합니다. 따라서 name1의 화살표(reference)가 가리키는 자료를 name2도 이미 가리키고 있기 때문에 name1을 통해 그 자료를 수정했을 때 결과적으로 name2는 별도로 수정해주지 않았음에도 값이 변경되어 있는 것이죠.
2️⃣ Reference가 할당되는 기준 ( object끼리 비교해보기)
Reference는 object를 할당할 때마다 새롭게 생성된다고 생각하면 됩니다.
const name1 = { name : '김' };
const name2 = { name : '김' };
object의 내용이 완전히 똑같은 두 개의 변수가 있습니다. 그렇다면 name1 == name2 를 하면 true가 나올까요? 그렇지 않습니다. object에는 값이 저장되는 것이 아니라 reference가 저장되는 것이고, 지금 object가 2개 생겼기 때문에 reference도 2개가 생겼을 것이기 때문에 name1과 name2는 서로 다른 reference를 가지고 있는 것입니다. 따라서 name1과 name2는 같지 않습니다.
3️⃣ 함수를 이용해서 object를 조작하는 경우
const name1 = { name : '김' };
function change(obj){
obj = { name : 'park' };
}
change(name1); // {name: '김'}
결과가 어떻게 나올까요? 결과는 {name: '김'} 이 나옵니다. 이것은 함수의 파라미터의 성질을 우선 알아야 이해가 가능합니다.
사실 함수를 만들 때 파라미터는 일종의 변수와 같다고 이해하시면 됩니다. 아래 코드를 보면 좀 더 이해가 잘 될 것입니다.
# 인간의 코드
const name1 = { name : '김' };
function change(obj){
obj = { name : 'park' };
}
change(name1);
# 자바스크립트가 이해하는 코드
const name1 = { name : '김' };
function change(obj){
obj = { name : 'park' };
}
change(const obj = name1);
change(const obj = name1); 이 부분이 중요합니다. 파라미터에 뭘 넣을 때 자바스크립트는 그것을 일종의 새로운 변수가 들어가는 것으로 이해합니다. 그러면 이 부분을 다시 코드로 써 보면 이렇게 됩니다.
const name1 = {name: '김'}
const obj = name1
obj = {name: 'park'} // 새로운 object를 재할당 (새로운 reference를 재할당)
이렇게 되면 오늘 공부한 것처럼 name1과 obj는 같은 reference를 공유하게 되고 따라서 {name: '김'} 을 공유하게 됩니다. 그런데 obj = {name: 'park'} 은 재할당된 object입니다. 새로운 reference를 재할당한 것이기 때문에 name1이라는 변수를 건드리지 않고 있습니다. 따라서 name1의 값은 변경되지 않습니다.
'Javascript' 카테고리의 다른 글
Javascript ES6 - 객체지향2 - Prototype (0) | 2022.01.17 |
---|---|
Javascript ES6 - 객체지향1 - Constructor (0) | 2022.01.17 |
코딩애플 - Javascript ES6 - Spread, rest 파라미터 연습문제 8번 (0) | 2022.01.15 |
Javascript ES6 - Rest parameter (0) | 2022.01.15 |
Javascript ES6 - Default Parameter & Arguments (0) | 2022.01.15 |