오늘은 객체지향 문법 시작 전 반드시 알아야할 reference, primitive data type을 알아봅시다.
Primitive data type
자바스크립트의 자료형 (문자, 숫자, array, object 등)은 자료형을 크게 2개로 분류합니다.
Primitive & reference라고 분류하는데
Primitive data type들은 그냥 별건 없고 자료 자체가 변수에 저장되는 자료들입니다.
문자, 숫자 자료형들이 대표적인 primitive data type들입니다.
이렇게 문자나 숫자 자료형은 문자나 숫자가 변수에 직접 저장된다는 소리입니다.
뭐 그런 당연한 소리를 하냐고요?
아닌 것들도 있기 때문입니다.
Reference data type
Array, Object 자료형은 reference data type에 속합니다.
reference data type은 자료를 변수에 직접 저장하는게 아닌,
자료가 저쪽에 있습니다 라는 화살표 (레퍼런스)를 변수에 저장합니다.
말이 어려우니 예를 들어봅시다.
여러분 방금 { name : 'Kim' } 이라는 자료를 변수에 저장했습니다.
하지만 변수에 저장된건 { name : 'Kim' } 이게 아닙니다.
"{ name : 'Kim' }이 저기 저장되어있습니다"라는
{ name : 'Kim' } 값을 가리키는 화살표가 저장이 되어있을 뿐입니다.
정확히는 메모리 주소가 저장되어 있는 것입니다.
알겠죠? Kim이라는 데이터가 변수에 저장된게 아닙니다. Kim이라는게 저기 있습니다~ 라는 정보만 저장할 뿐입니다.
그래서 이런 reference만 저장되는 array, object 자료형을 reference data type이라고 합니다.
Q. 화살표가 가리키는 저기가 어딘데요?
A. 컴퓨터 메모리 상의 어떤 곳입니다. 그냥 우리는 컨트롤할 수 없는 미지의 공간이라고 생각하셔도 됩니다.
어디서 이상한 C언어 배우다온 분들은 포인터인가? 라고 생각할 수 있는데 비슷합니다.
다만 C언어처럼 포인터 주소같은 개념은 다루지 못합니다.
아무튼 그래서 reference data type은 신기한 현상들이 일어납니다.
예제 1. 복사하면 이상한 일이 일어납니다.
한번 아주 직관적이고 간단한 Primitive 자료형부터 복사해보도록 합시다. 문자말입니다 문자.
(1) 이름1은 '김'이라는 문자를 집어넣었고
(2) 이름2는 이름1에 있던 자료를 복사해서 집어넣습니다. (등호는 그냥 집어넣는다라는 뜻입니다 같다는게 아니고요)
(3) 셋째줄에서 이름1을 심심해서 박으로 변경했습니다.
그럼 이름1, 이름2를 출력하면 각각 무엇이 나올까요?
이름1은 변경했으니 '박'이고, 이름2는 복사만했지 변경하진 않았으니 '김' 입니다.
끝입니다. 별로 이상한 점이 없습니다.
근데 똑같은 일을 reference data type으로 진행하면 이상한 일이 일어납니다.
한번 Reference 타입 자료형인 object를 이용해 똑같이 해보도록 하겠습니다.
(1) 이름1은 { name : '김' } 이라는 object자료형을 집어넣었고
(2) 이름2는 이름1에 있던 자료를 복사해서 집어넣습니다.
(3) 셋째줄에서 이름1 object 안의 name을 박으로 변경했습니다.
그럼 이름1, 이름2를 출력하면 각각 무엇이 나올까요?
이름1은 변경했으니 { name : '박' } 이고, 이름2는 복사만했지 변경하진 않았으니 { 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 자료형은 등호로 복사하시면
화살표 값을 공유해버리기 때문에 문제가 일어날 수 있습니다.
그래서 다음포스팅에서 알아볼 constructor 문법을 쓰셔서 object를 복사하든가 하시면 안전합니다.
예제 2. 화살표가 할당되는 기준 & object 두개가 같은지 비교해보기
여러분이 새로운 {} object를 할당할 때마다 화살표가 새로 생성된다고 보시면 됩니다.
정확한 명칭은 reference 지만 기억에 오래 남게 화살표라고 합시다.
지금 첫줄과 둘째줄 모두 object를 새로 할당해주고 있습니다.
실은 object가 저기 있다는 화살표를 할당해준 것입니다. 끝입니다.
그럼 이걸 한번 보도록 합시다.
지금 첫줄과 둘째줄 모두 object를 새로 할당해주고 있습니다. 근데 object 안의 내용이 똑같네요.
여기서 잠깐!
Q. 바로 위의 예제에서 이름1 == 이름2 이렇게 두개를 같다고 비교하면 true가 나올까요 false가 나올까요?
A. false가 나옵니다.
Why??
왜냐면 이름1과 이름2에 저장된건 데이터가 아니라 화살표랬죠?
== 등호로 비교하고 계신건 지금 object 두개가 아닙니다. 화살표 두개입니다.
화살표가 같으면 (같은 곳을 가리키면) true가 나오고, 화살표가 같지 않으면 false가 나오기 때문입니다.
위의 예제코드를 그림으로 표현하자면 이렇습니다.
각각 다른 화살표를 가지고 있기 때문에 이름1과 이름2는 같지 않습니다.
잘 기억해주시면 됩니다. array도 마찬가지입니다. 함부로 같다고 비교하시면 안됩니다.
굳이 값이 같은지 비교하고 싶으면 이름1.name과 이름2.name을 비교해보십시오.
예제 3. 함수를 이용해 object를 변경하면 어떻게 될까
object를 = 등호를 이용해 조작하면 뭔가 일이 일어나는거 같으니까
이번엔 한번 함수를 이용해서 object 조작 기계를 만들어보겠습니다.
말되죠? 변경() 이라는 함수를 만들었는데,
이 함수는 뭔가 오브젝트를 입력하면 오브젝트 내용을 { name : 'park' } 으로 재할당해주는 함수입니다.
그래서 이름1을 집어넣어서 실행해봤습니다.
Q. 근데 실행해봐도 이름1은 바뀌지 않습니다. 왜 그럴까요?
왜그러냐면 여러분 함수 만들 때 파라미터라는거 만들잖아요.
파라미터는 일종의 변수처럼 생성되고 사라지는 존재라고 보시면 됩니다.
그냥 쉽게말하면 var 변수에요 변수
자바스크립트가 파라미터를 만들고 사용할 땐 대충 맨 밑줄처럼 만든다고 생각하시면 됩니다.
(실제 이런 문법이 있는건 아니지만요)
obj라는 파라미터자리에 이름1이라는 변수를 집어넣으시면
var obj = 이름1 이렇게 파라미터형 변수를 만든겁니다.
음 근데 이거 계속 보던 패턴이지 않나요?
obj 라는 변수에 이름1이라는 { object } 를 등호로 복사해서 넣으면 어떻게 되나요?
obj, 이름1 이 두개 변수는 서로 같은 화살표를 갖게 되며 { name : '김' } 값을 공유합니다.
그런데 함수 내부를 잘 보시면 obj라는 변수는 obj = { name : 'Park' } 이렇게 재할당을 해주고 있죠?
이것은
obj라는 변수에 새로운 화살표를 재할당을 한 것이지
실제 이름1이라는 변수는 전혀 건드리지 않고 있습니다.
그래서 결국 이름1은 바뀌지 않는 것입니다.
▼ 그럼 밑의 예제코드는 실행하면 콘솔창에 무엇이 출력될까요??
한번 예상해보신 다음 실제 실행해보셔서 출력결과랑 맞춰보시길 바랍니다.
출처 : 코딩애플의 매우쉽게 이해하는 JavaScript 객체지향 & ES6 신문법
'JavaScript > ES6' 카테고리의 다른 글
[OOP]prototype (0) | 2022.08.25 |
---|---|
[OOP]Constructor (0) | 2022.08.25 |
[ES6]Spread, rest parameter 연습문제 (0) | 2022.08.24 |
[ES6]Rest Parameter (0) | 2022.08.24 |
[ES6]자바스크립트 함수 업그레이드(default parameter/arguments) (0) | 2022.08.24 |