자바스크립트의 데이터타입은 크게 기본형,참조형으로 나뉜다.
기본형
Number
Int, long, float, double와 같이 다양한 숫자 타입이 존재하는 C언어와 다르게 자바스크립트에는 단하나의 숫자 타입이 존재한다. 모든 숫자를 64비트 부동 소수점 형태로 저장한다(정수와 실수구분 x)
String
문자열의 길이에는 상관없이 String이라는 데이터 타입으로 값이 생성된다.
Boolean
false, true의 값이 존재한다 (거짓, 참)
undefined, null
null은 명시적으로 값이 비어있을 때 사용한다.
반면에 undefined는 값이 할당되어야 하는데 비어있을 때 사용한다.
Symbol
충돌 위험이 없는 고유한 프로퍼티를 만들기위한 데이터 타입이다.
참조형
객체
기본타입을 제외한 모든 값은 객체로 취급된다.
배열이나 함수등도 모두 객체!
배열 - 키(key)와 특정 배열별 동작을 갖춘 객체, index를 key로 가지며 length를 갖는 특수한 객체이다.
함수 - 1급객체라고 표현하기도 한다.
1급객체
1. 변수나 데이터 구조안에 담을 수 있다.
2. 파라미터로 전달할 수 있다.
3. 반환값으로 사용할 수 있다.
4. 동적으로 프로퍼티 할당이 가능하다.
=> 입력값을 받아 결과를 반환하는 구조이다.(다른언어와 비슷한점)
함수자체가 값으로 분류된다(다른 언어와 차이점)
값으로 취급되어야 1급객체의 특징을 만족한다.
변수 선언과 할당
자바스크립트에서는 변수선언과 할당을 변수영역과 데이터영역으로 나누어서 선언과 할당을 진행한다.
이렇게하는 이유는 무엇일까?
- 데이터 변환을 자유롭게 할수있게 하고 메모리를 더욱 효율적으로 관리할 수 있다.
- 미리 확보한 공간내에서만 데이터를 변환할 수 있다면 변환한 데이터를 다시 저장할 때 확보된 공간을 변환된 크기에 맞게 늘리는 작업이 필요하다 => 만약 맨뒤를 늘린다면 쉽게 늘릴 수 있지만, 중간데 데이터를 늘려야 한다면 뒤에 데이터를 전부 뒤로, 이동시킨 데이터를 식별자에 연결해야한다 이렇게 되면 매우 비효율 적이다.
이러한 이유 때문에 문자열 데이터의 변환을 처리하려면 변수와 데이터를 별도의 공간에 나누는 것이 최적이다.
a = 'abc' // a를 변수 영역에 할당하고 abc를 데이터 영역에서 찾고 없으면 abc를 데이터 영역에 생성 후 변수 a에 할당
a = 'abcdef' // 'abcdef'를 데이터 영역에 생성하고 a에 할당
위의 코드는 예시이다.
처음에 식별자 a를 변수 영역에 생성한다.
그다음 'abc'를 데이터 영역에서 검색한다. 존재하지 않을 시 데이터 영역의 빈 공간에 'abc'를 생성하고 a에 주소값을 할당한다.
'abcdef'는 'abc'뒤에 추가하는 것이 아니라 새롭게 'abcdef'라는 문자열을 데이터 영역에 생성하여 a에 주소값을 새롭게 할당한다.
이번엔 숫자형으로 예시를 들어보겠다.
예로 5를 100개의 변수에 할당하는 경우를 보면
각 변수를 별개로 구분하려면 100개의 변수 영역을 생성하는 것은 불가피하다.
그럼 각 변수마다 숫자 5를 할당하는경우, 변수영역, 데이터영역을 구분하고 데이터 영역에 숫자 5를 생성하고 각 주소에 할당하는 방법중에 후자가 메모리적으로 효율적이다.
불변성
변수 - 바뀔 수 있는 값
상수 - 바꿀 수 없는 값
불변성 여부를 구분할때는 데이터영역 메모리
기본형데이터는 모두 불변성이다 => 변경은 오직 새로 만드는 작업을 통해 이뤄진다.
가변값
참조형 - 기본형 데이터와의 차이 => 객체의 변수(프로퍼티)영역이 따로 존재
중첩객체 - 참조형안에 다시 참조형을 할당
// 중첩객체 예시
obj ={
x : 3,
arr : [3,4,5],
}
변수 복사 비교
참조형은 한단계를 더 거친다 => 값을 변경할 때 최상위 부분(객체와 직접적으로 연관되어있는 프로퍼티)의 주소는 변하지 않게된다. => 프로퍼티 변경은 해당 프로퍼티의 데이터 영역의 주소만 바뀐다.
객체 자체변경은 객체 자체에 새로운 주소를 할당하여서 값이 변경된다.
프로퍼티란?
객체 - 기본형 데이터를 제외한 나머지 값들
객체는 키와 값으로 구성된 프로퍼티들의 집합
프로퍼티의 값으로 자바스크립트에서 사용할 수 있는 모든 값 사용가능
자바스크립트에서 함수는 일급객체이므로 값으로 사용할수있다.
-> 따라서, 프로퍼티의 값이 함수일 수 있으며, 프로퍼티의 값이 함수일경우 구분하기위해 메서드라고 불린다.
얕은복사, 깊은복사
얕은복사 - 바로 아래단계의 값만 복사하는 방법
문제점: 중첩된객체에서 참조형데이터가 저장된 프로퍼티를 복사할 때 그 주소값만 복사한다.
-> 이러면 해당 프로퍼티의 원본과 사본이 모두 동일한 참조형데이터의 주소를 가리키게 된다.
-> 원본을 바꾸면 사본도 바뀌고 사본을 바꾸면 원본도 바뀌게된다.
얕은복사를 하였을때 => 즉, 객체에 직접속한 프로퍼티는 위의 현상이 일어나지 않지만, 중첩객체에서는 문제점이 발생한다.
중첩된객체에대한 얕은복사의 문제점 해결 - 깊은복사
깊은복사를 하는방법 - 객체의 프로퍼티 중에서 그 값이 기본형 데이터인 경우에는 그대로 복사
참조형 데이터는 다시 그 내부의 프로퍼티들을 복사해야 한다.
=> 이렇게 깊은복사를 하면 원본과사본이 서로 완전히 다른 객체를 참조하게 되며 어느쪽의 프로퍼티를 변경해도 다른쪽에 영향을 주지 않는다.
undefined와 null
undefined - 사용자가 명시적으로 지정할 수도 있지만 값이 존재하지 않을 때 자바스크립트 엔진이 자동부여
자동부여 할 때 - 사용자가 어떤 값을 지정할 것이라고 예상되는 상황임에도 실제로는 그렇게 하지 않을때
1. 값을 대입하지 않은 변수, 즉 데이터영역의 메모리 주소를 지정하지 않은 식별자에 접근
2. 객체 내부에 존재하지 않는 프로퍼티에 접근
3. return 문이 없거나 호출되지 않는 함수의 실행결과
undefined는 '비어있는' 요소와 다르다.
=> '비어있는'요소는 순회에서 제외, undefined는 순회를 한다.
=> undefined는 '하나의 값'으로 동작한다 => "값이 없음"이라는 값을 가진다.
null의 typeof null은 object이다.
이것은 자바스크립트의 자체버그이다.
어떤 변수의 값이 null인지 여부를 판별하려면 typeof대신 다른 방법으로 접근해야 한다.
null == undefined => true
null === undefined => false
동등연산자(==)는 구분을 못한다, 대신 일치연산자(===)를 사용하여야 한다.
'javascript Deep Dive' 카테고리의 다른 글
[JavaScript] This (0) | 2023.12.22 |
---|---|
[JavaScript] 실행 컨텍스트 (2) | 2023.12.21 |
[JavaScript] 배열과 시간복잡도 (0) | 2023.12.20 |
[JavaScript] map function (0) | 2023.12.20 |
[Javascript] 일급객체/ 일급함수 (0) | 2023.12.20 |