자바스크립트의 자료형(문자, 숫자, array, object 등)은 자료형을 크게 2개로 분류한다.
Primitive & reference라고 분류하는데
Primitive data type들은 자료 자체가 변수에 저장되는 자료들이다.
문자, 숫자 자료형들이 대표적인 Primitive data type들이다.
var name = 'john';
var age = 20;
이렇게 문자나 숫자 자료형은 문자나 숫자가 변수에 직접 저장된다는 소리다.
Array, Object 자료형은 referenece data type에 속한다.
referenece data type은 자료를 변수에 직접 저장하는게 아닌,
자료가 저쪽에 있습니다 라는 화살표(레퍼런스)를 변수에 저장한다.
var 사람 = { name : 'Kim' };
방금 { name : 'Kim' } 이라는 자료를 변수에 저장했다
하지만 변수에 저장된건 { name : 'Kim' } 이게 아니다.
"{ name : 'Kim' }이 저기 저장되어있습니다"라는
{ name : 'Kim' } 값을 가리키는 화살표가 저장이 되어있을 뿐이다
Kim이라는 데이터가 변수에 저장된게 아니고, Kim이란느게 저기 있습니다~ 라는 정보만 저장할 뿐이다.
그래서 이런 reference만 저장되는 array, object 자료형을 referenece data type이라고 한다.
A. 컴퓨터 메모리 상의 어떤 곳이다.그냥 우리는 컨트롤할 수 없는 미지의 공간이라고 생각하면 된다.
한번 아주 직관적이고 간단한 Primitive 자료형부터 복사해보자
var 이름1 = '김';
var 이름2 = 이름1;
이름1 = '박';
(1) 이름1은 '김'이라는 문자를 집어넣었고
(2) 이름2는 이름1에 있던 자료를 복사해서 집어넣는다.
(3) 셋재줄에서 이름1을 심심해서 박으로 변경했다.
그럼 이름1, 이름2를 출력하면?
이름1은 변경했으니 '박'이고, 이름2는 복사만했지 변경하진 않았으니 '김'이다.
근데 똑같은 일을 reference data type으로 진행하면 이상한 일이 일어난다.
Reference 타입 자료형인 object를 이용해 똑같이 해보자
var 이름1 = { name : '김' };
var 이름2 = 이름1;
이름1.name = '박';
(1) 이름1은 { name : '김' } 이라는 object자료형을 집어넣었고
(2) 이름2는 이름1에 있던 자료를 복사해서 집어넣었다.
(3) 셋째줄에서 이름1 object 안의 name을 박으로 변경다.
그럼 이름1, 이름2를 출력하면?
이름1은 변경했으니 { name : '박' }이고, 이름2는 복사만했지 변경하진 않았으니 { name : '김' }이다.
그런데 콘솔창에서 출력해보면 이상한 점이 있다.
분명 코드를 보면
var 이름1 = { name : '김' };
var 이름2 = 이름1;
이름1.name = '박';
이름2는 우리가 값을 전혀 수정한 적이 없는데 바뀌어 있다.
왜 그러냐면 두번째줄이 문제이다.
이름2에 이름1을 복사해서 집어넣을 때가 문제이다.
이 때, 이름1에 있던 { name : '김' }이라는 데이터가 복사된게 아니다.
왜냐면 이름1에는 {} 이게 저장된게 아니라 reference(화살표)가 저장되어 있다고 했으니
이름1의 화살표를 이름2에 복사한 것이다.
이제 이름1과 이름2는 같은 화살표를 가지고 있다.
이름1과 이름2는 같은 화살표(reference)를 가지게 된 것이고
그 화살표는 { name : '김' }이라는 같은 값을 가리키고 있는 것일 뿐이다.
그럼 아까 코드에서 셋째줄에서 이름1.name = '박' 이렇게 값 변경을 하면 어떻게 될까?
화살표를 타고 들어갓거 name을 '박'으로 설정해준다.
근데 가만히 있던 이름2를 출력해보면
화살표를 타고 들어가서 { name: '박' } 이라는 데이터가 나오게 되는 것이다.
이런 원리 때문에 이름1과 이름2는 같은 값을 공유하고 있던 것이다.
결론은 object, array 자료형은 등호로 복사하면
화살표 값을 공유해버리기 대문에 문제가 일어날 수 있다.
새로운 {} object를 할당할 때마다 화살표가 새로 생성된다고 보면 된다.
정확한 명칭은 reference이다.
var 이름1 = { name : '김' };
var 이름2 = { name : '박' };
지금 첫줄과 둘째줄 모두 object를 새로 할당해주고 있다.
실은 object가 저기 있다는 화살표를 할당해준 것이다.
var 이름1 = { name : '김' };
var 이름2 = { name : '김' };
지금 첫줄과 둘째줄 모두 object를 새로 할당해주고 있다. 근데 object 안의 내용이 똑같다.
A. false가 나온다.
왜냐면 이름1과 이름2에 저장된건 데이터가 아니라 화살표라고 했다.
== 등호로 비교하고 있는건 지금 object 두개가 아니다. 화살표 두개이다.
화살표가 같으면 (같은 곳을 가리키면)true가 나오고, 화살표가 같지 않으면 false가 나오기 때문이다.
각각 다른 화살표를 가지고 있기 때문에 이름1과 이름2는 같지 않다.
잘 기억해주면 된다. array도 마찬가지이다. 함부로 같다고 비교하시면 안된다.
굳이 값이 같은지 비교하고 싶으면 이름1.name과 이름2.name을 비교해보자
var 이름1 = { name : '김' };
function 변경(obj){
obj = { name : 'park' };
}
변경(이름1);
변경() 이라는 함수를 만들었는데,
이 함수는 뭔가 오브젝트를 입력하면 오브젝트 내용을 { name: 'park' }으로 재할당해주는 함수이다.
그래서 이름1을 집어넣어서 실행해봤다.
파라미터는 일종의 변수처럼 생성되고 사라지는 존재라고 보면된다.
(인간의 시점)
var 이름1 = { name : '김' };
function 변경(obj){
obj = { name : 'park' };
}
변경(이름1);
(자바스크립트의 시점)
var 이름1 = { name : '김' };
function 변경(obj){
obj = { name : 'park' };
}
변경(var obj = 이름1);
자바스크립트가 파라미터를 만들고 사용할 땐 대충 맨 밑줄처럼 만든다고 생각하면 된다.
obj라는 파라미터자리에 이름1이라는 변수를 집어넣으면
var obj = 이름1 이렇게 파라미터형 변수를 만든것이다.
var 이름1 = { name : '김' };
function 변경(obj){
obj = { name : 'park' };
}
변경(이름1);
obj 라는 변수에 이름1이라는 {object]를 등호로 복사해서 넣으면?
obj, 이름1 이 두개 변수는 서로 같은 화살표를 갖게 되며 { name: '김' } 값을 공유한다.
그런데 함수 내부를 잘보면 obj라는 변수는 obj = { name: 'Park' } 이렇게 재할당해주고 있다.
이것은 obj라는 변수에 새로운 화살표를 재할당을 한 것이지 실제 이름1이라는 변수는 전혀 건드리지 않고 있다.
그래서 결국 이름1은 바뀌지 않는 것이다.