효습
1.데이터 타입 본문
1. 데이터 타입
자바스크립트에는 크게 기본형(primitive type)과 참조형(reference type)이 있음
기본형(primitive type) :
- Number , String , Boolean , null , undefined ,Symbol
- 할당이나 연산시에 값이 담긴 주소값을 바로 복제한다.
- 불변성(immutability)을 띔
참조형(reference type):
- Array ,Function , Date , RegExp , (Map, WeakMap) , ( Set ,WeakSet)
- 할당이나 연산시에 참조되며 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주소값을 복제한다.
자바스크립트는 숫자의 경우 정수형인지 부동소수형인지를 구분하지 않고 64비트 , 즉 8바이트를 할당함
식별자는 어떤 데이터를 식별하는데 사용하는 이름 , 즉 변수명임
var a = 'abc';
임의로 1003번에 변수명 a를 저장하고 ‘abc’는 별도의 메모리 공간에 저장하고 그 주소를 변수 영역에 저장함
문자열은 정해진 규격이 없음
효율적으로 데이터의 변화를 처리하려면 변수와 데이터를 별도의 공간에 나누어서 저장하는 것이 최적임
기존 문자열에 어떤 변환을 가하든 상관 없이 무조건 새로 만들어 별도의 공간에 저장함
문자열 값도 한 번 만든 값을 바꿀 수 없고 , 숫자 값도 다른 값으로 변경할 수 없다. 변경은 새로 만드는 동작을 통해서만 이루어지고 이게 불변값의 성질임
한번 만들어진 값은 가비지 컬렉팅을 당하지 않는 이상 영원히 변하지 않음
참조형 데이터와 기본형 데이터의 가장 큰 차이는 ‘객체의 변수(프로퍼티) 영역’이 별도로 존재한다는 점이다
어떤 데이터에 대해 자신의 주소를 참조하는 변수의 개수를 참조 카운트라고 함
참조 카운트가 0인 메모리 주소는가비지 컬렉터의 수거대상이 된다.
가비지 컬렉터는 런타임 환경에 따라 특정 시점이나 메모리 사용량이 포화 상태에 임박할 때마다 수거 대상들을 수거하여 새로운 값을 할당할 수 있는 빈 공간을 만든다.
어떤 데이터 타입이든 변수에 할당하기 위해서는 주솟값을 복사해야함
기본값은 주솟값을 복사하는 과정이 한 번만 이루어지고 , 참조형은 한 단 계를 더 거치게 됨
참조형 데이터의 경우 객체의 프로퍼티를 변경했을 때와 객체 자체를 변경했을 때는 차이가 있음
객체 자체를 변경했을 때에는 메모리의 데이터 영역의 새로운 공간에 새 객체를 생성하고 그 주소를 변수 영역에 저장함
참조형 데이터가 ‘가변값’이라고 설명할 때의 ‘가변’은 참조형 데이터 자체를 변경할 경우가 아니라 그 내부의 프로퍼티를 변경할 때에만 성립함
얇은 복사(shallow copy) : 바로 아래 단계의 값만 복사하는 방법
깊은 복사(deep copy) : 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법
var copyObject = function(target){
var result ={};
for (var prop in target){
result[prop] = target[prop];
}
return result;
};
중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사한다는 의미
그러면 해당 프로퍼티에 대해 원본과 사본이 모두 동일한 참조형 데이터의 주소를 가리키게 됨.
사본을 바꾸면 원본이 바뀌고 , 원본을 바꾸면 사본도 바뀜
객체에 직접 속한 프로퍼티에 대해서는 복사해서 완전히 새로운 데이터가 만들어지지만 한 단계 더 들어간 중첩된 객체의 내부 프로퍼티들은 기존 데이터를 그대로 참조함
var copyObjectDeep = function(target){
var result = {};
if(typeof target ==='object' && target !=null){
for(var prop in target){
result[prop] = copyObjectDeep(target[prop]);
}
} else {
result = target;
}
return result;
};
target이 객체인 경우에는 내부 프로퍼티들을 순회하면 copyObjectDeep 함수를 재귀적으로 호출하고 , 객체가 아닌 경우에는 target을 그대로 지정하게끔 함
이 함수를 이용해서 객체를 복사한 다음에는 원본과 사본이 서로 완전히 다른 객체를 참조하게 되어 어느 쪽의 프로퍼티를 변경하더라도 다른 쪽에 영향을 주지 않음
간단하게 깊은 복사를 처리할 수 있는 다른 방법:
객체를 JSON 문법으로 표현된 문자열로 전환했다가 다시 JSON 객체로 바꾸는 방법
다만 메서드(함수)나 숨겨진 프로퍼티인 proto나 getter/setter등과 같이 JSON으로 변경할 수 없는 프로퍼티들은 모두 무시하기때문에 httpRequest로 받은 데이터를 저장한 객체를 복사할 때 등 순수한 정보만 다룰 때 활용하기 좋다.
아니면 라이브러리 활용
자바스크립트 엔진이 undefined를 반환하는 경우
- 값을 대입하지 않은 변수 , 즉 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때
- 객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때
- return문이 없거나 호출되지 않는 함수의 실행 결과
배열은 객체와 마찬가지로 특정 인덱스에 값을 지정할 때 비로소 빈 공간을 확보하고 인덱스를 이름으로 지정하고 데이터의 주솟값을 저장하는 등의 동작을 한다. 즉 , 값이 지정되지 않은 인덱스는 ‘아직은 존재하지 않는 프로퍼티’임
ES6에서 등장한 let , const에 대해서는 undefined로 할당하지 않은 채로 초기화를 마치며 , 이후 실제 변수가 평가되기 전까지는 해당 변수에 접근할 수 없음
‘비어있음’을 나타내고 싶을 때에는 undefined 말고 null을 쓰면 됨
typeof null은 object임 - 자바스크립트 자체 버그
'스터디 > Javascript' 카테고리의 다른 글
2.실행 컨텍스트 (0) | 2022.11.22 |
---|---|
3.this (5) | 2022.11.22 |