ES6에 자바스크립트의 데이터 타입은 7가지이다. 숫자 타입
, 문자열 타입
, 불리언 타입
, undefined타입
, null타입
, 심벌 타입
, 객체 타입
이 그 7가지이다. 이 7가지 타입은 원시 타입과 객체 타입으로 분류할 수 있는데 숫자
, 문자열
, 불리언
, undefined
, null
, 심벌 타입
은 원시 타입이다. 그리고 객체
, 함수
, 배열
등이 객체 타입이다.
원시 타입과 객체 타입은 무엇이 다를까
원시값과 객체값의 다른 점은 변경 가능 여부이다. 이때 변경이 불가능하다는 것은 하나의 변수에 다른 값을 할당하지 못한다는 이야기가 아니라 원시값 자체를 변경할 수 없다는 것을 의미한다. 메모리에 저장된 실제 값을 직접 건드릴 수 없고 새로운 메모리를 할당해야 한다는 것이다.
문자열을 예로 들어보자. 일단 문자열은 원시 타입인 동시에 유사 배열 객체이다. 유사 배열 객체란 배열과 유사하게 접근할 수 있는 것을 말한다. 배열에 인덱스를 통해 접근하고 반복문을 돌릴 수 있는 것 처럼 문자열도 인덱스를 사용해 각 문자에 접근할 수는 있다. 그러나 배열과 다른 점은 수정을 못한다는 것이다.
var str='string';
console.log(str[2]); // r
str[2]=''; // 에러는 발생하지 않지만 실패
위의 코드는 아마 str
의 2번 인덱스 문자를 변경하고자 한다. 그러나 문자열은 원시 타입이기 때문에 값을 부분적으로 변경할 수 없다. 아예 다른 값으로 재할당해야 하는 것이다. 다음의 예를 통해 다른 값을 재할당 할 시 메모리 주소는 어떻게 변경되는 지 확인해보자
var str='string';
str='sting';
메모리 임의의 주소에 식별자 str
을 만들고 그 안에 ‘string’
이라는 값을 저장한다. 이제 값을 ‘sting’
으로 재할당할 차례이다. 원시 타입은 새로운 주소에 str
을 다시 할당한 후 ‘sting’
이라는 값을 저장한다.
따라서 만약 아래처럼 copy
라는 변수에 80이라는 원시 값을 갖는 변수를 할당하면 할당받는 변수 copy
에는 원시 값이 복사되어 전달된다. 이를 값에 의한 전달이라고 하며 깊은 복사에 해당한다.
객체는 원시 타입과 달리 변경 가능하다. 따라서 프로퍼티 값을 갱신하거나 프로퍼티를 동적으로 생성할 수 있다. 원시 타입은 메모리 주소에 실제 값을 저장했지만 객체 타입에서는 참조 값을 저장한다. 실제값까지 접근하는데 하나의 다리가 더 있는 셈이다. 변수 안에는 실제 값을 참조하고 있는 주소값이 들어있는 것이다.
이러한 객체 타입을 복사할 때는 어떤 일이 일어날까? 객체를 가리키는 변수를 다른 변수에 할당하면 실제 값이 복사가 되는 것이 아니라 원본의 참조 값이 복사되어 전달된다. 이를 참조에 의한 전달이라고 하며 얕은 복사에 해당한다.
var person={
name: 'Lee'
};
var copy=person;
이렇게 되면 객체 원본의 참조값을 변수 person과 copy 모두 가진다. 따라서 하나의 변수에서 값을 수정해도 다른 변수까지 그 수정이 반영된다. 즉, 두개의 식별자가 하나의 객체를 공유하는 것이다.