종류 : 문자열, 숫자, 불리언, symbol, undefined, null
특징
- 원시 자료형을 변수에 할당하면 데이터 값이 메모리 공간에 담긴다.
- 원시 값을 가지는 변수를 다른 변수에 할당하면 원시 값 자체가 복사되어 전달된다.
3. 원시 자료형은 변경 불가능한 값이다.(읽기 전용 값)
변경불가능한 값이란?
변수에 값을 할당하고 재할당하는 경우에는 기존의 원시 값 자체가 변경된 것이 아니라 새로운 원시 값을 생성하고, 변수가 다른 메모리 공간을 참조함.let num =20 ; // 값의 할당 num =30; // 값의 재할당
이런 경우에 20 이 있던 메모리 공간에 30이라는 값을 저장하는게 아닌
새로운 메모리 주소의 공간에 30의 값을 저장하는 것 그래서 변경불가능한 값이라 함
기존 값 20이 담겨 있던 메모리 공간은 가비지 콜렉터에 의해 값이 삭제 됨!
원시 자료형은 메모리 공간에 값이 직접 담기기 때문에 복사가 용이하다.
값을 복사한 변수에다 다른 값을 할당하거나 해도 기존 값이 담긴 변수의 값은 그대로 이다.let num =10; let copiedNum = num ; copiedNum =20; // 기존의 값 10에서 20으로 값 변경 num ; // 10 // 그래도 num 에는 기존 값인 10 이 담겨 있다.
종류 : 배열, 객체, 함수
특징
- 참조 자료형을 변수에 할당하면 메모리 공간에
주솟값이
저장됨.
어떤 주소값?
배열, 객체, 함수 는 메모리가 차지하고 있는 공간 일부를 없애고 그 공간에heap
이라는 공간을 만들어 이 곳에 데이터 값을 저장하고 있는 것. 변수가 가지고 있는 메모리 공간에는 이 주소가 적혀 있는 것!
2. 참조 값을 갖는 변수를 다른 변수에 할당하면 주솟값이 복사되어 전달 됨.즉,
변수1(arr) 과 변수2(copiedArr)
는 서로 같은 주소 값을 바라보고 있는 것!
arr
의 참조 자료형을 수정해도copiedArr
에도 영향이 가고 반대의 경우에도 동일하게 영향이 간다는 것!
3. 참조 자료형은 변경가능한 값원시 자료형의 경우 값의 크기가 거의 일정하기 때문에 새로운 공간을 확보하여 값을 복사하는 방법이 유용하지만,
크기가 일정하지 않은 참조 자료형의 경우 매번 값을 복사하는 방법은 효율성이 떨어짐.
이런 이유로 참조 자료형은 값의 변경이 가능하도록 설계되어 있음.
원시 자료형
을 할당한 변수를 다른 변수에 할당하면 값 자체의 복사
가 일어나
둘 중 하나의 값을 변경해도 다른 하나의 변수에는 영향을 미치지 않는다.
참조 자료형
을 할당한 변수를 다른 변수에 할당하는 경우에는 주솟값을 복사
하기 때문에
둘 중 하나의 변수가 값을 변경한다면 다른 하나의 변수에도 영향을 미친다.
참조 자료형도 원시 자료형처럼 원본과 복사본이 서로 영향을 미치지 않도록 복사하는 방법은 없을까?
할 수 있지만 얕은 복사와 깊은 복사
가 존재한다.
알아보도록 하자!
slice(), spread 연산자, Object.assign()
을 사용하여 참조 자료형을 복사를 할 수 있는데
만약 참조 자료형이 중첩
으로 되어 있다면?
위 사진과 같이 참조 자료형 안에 참조 자료형이 중첩으로 들어 있는 경우라면
slice(), spread 연산자, Object.assign()
으로는 가장 외부에 있는 참조 자료형만 복사가 된다. 내부에 있는 참조 자료형은 여전히 같은 주솟값을 참조한다는 것! 이것이 얕은 복사이다.
slice()
원본과 동일한 복사본을 만들 수 있음
spread 연산자
[...arr] ES6 에서 새롭게 추가된 문법으로 slice() 와 동일하게 복사본 생성 가능주솟값이 다르기 때문에 서로에게 영향을 끼치지 못함.
Object.assign()
: 원본과 동일한 복사본 만들 수 있음
spread 연산자
{...obj} 객체에서도 사용가능.
얕은 복사에서 하지 못한 내부 중첩된 참조 자료형까지 복사하는 것을 말한다.
그.런.데 JavaScript 내부적으로는 깊은 복사를 수행할 수 있는 방법이 없다.!
JavaScript의 다른 문법인 JSON 문법
을 이용해서 깊은 복사
를 해야한다!!
JSON.stringify()
와 JSON.parse()
를 이용하는 것!
JSON.stringify()
참조 자료형을 ---> 문자열 형태로 변환
JSON.parse()
문자열 형태를 ---> 객체로 변환즉,
JSON.stringify()
를 사용하여 문자열 형태로 변환하고JSON.parse()
를 사용해 깊은 복사와 같은 (내부 중첩된 참조 자료형까지 복사된) 결과물을 얻을 수 있다.
하지만 이 방법도 예외가 존재하는데 만약 내부 중첩된 참조 자료형이 함수면 JSON 문법을 사용해서 깊은 복사를 구현하면 함수가 null로 바뀌게 됨
완전한 깊은 복사를 반드시 해야하는 경우라면 node.js 환경에서 외부 라이브러리인 lodash, 또는 ramda를 사용하면 가능하긴 하다!