일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- GitLab
- nextJS
- git
- commit
- react-native
- Xcode
- npm
- currying
- Docker
- npm install
- REACT
- styling
- github
- ReactNative
- HTML
- vscode
- styled-components
- rn
- JavaScript
- xtring.log
- js
- Android
- shortcut
- ES6
- ios
- Swift
- React Native
- Branch
- viewcontroller
- DevOps
- Today
- Total
xtring.dev
[JS] 01 데이터 타입 - 데이터 타입과 변수 선언 본문
01 데이터 타입의 종류
(1) 기본형(원시형, primitive type): number
, string
, boolean
, null
, undefined
, Symbol
(ES6에서 추가)
(2) 참조형(reference type): object
- Array
, Function
, Date
, RegExp
등... (ES6에서 Map
, Set
, WeakSet
등이 추가)
기본형 데이터 타입은 값이 담긴 주소값을 바로 복제합니다. 또한 불변성(immutability) 이라는 특성을 가지고 있습니다. (불변성 은 메모리와 데이터에 대한 지식이 필요함으로 이후 포스터에서 다루겠습니다.)
참조형 데이터 타입은 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주솟값을 복제합니다.
02 데이터 타입을 이해하기 위해서
모든 데이터는 바이트 단위의 식별자 즉, 메모리 주소값(memory address)을 통해 서로 구분하고 연결합니다. memory의 주소값에 대한 이해를 위해서는 bit와 byte의 단위를 이해하고 있어야합니다.
bit는 컴퓨터의 가장 단위이며 0과 1만 표현할 수 있는 하나의 메모리 조각입니다. 각 비트는 고유한 식별자를 통해 구체적인 위치를 확인할 수 있습니다. 하지만 모든 bit의 각각의 위치를 확인하는 것은 매우 비효율적입니다. 따라서 bit를 8개로 묶은 단위인 byte가 생겼습니다. 1bit는 0 또는 1 두 가지 값을 표현할 수 있으므로 1btye는 2에 8승(256)개 값을 표현할 수 있습니다.(1Byte = 8bit)
변수(variable)과 식별자(identifier)는 분명히 구분되어 있습니다. '변수'는 '변할 수 있는 수; 변할 수 있는 무언가'라는 의미입니다. 하지만 반드시 값이 숫자여야 하는 것은 아닙니다. 따라서 '데이터'를 의미합니다. 그리고 숫자, 문자열, 객체, 객체 모두 데이터입니다. '식별자'는 어떤 데이터를 식별하는데 사용하는 이름 , 즉 '변수명'입니다.
03 변수 선언
var a;
변수 선언은 풀어서 말하면 '변할 수 있는 데이터를 만든다. 이 데이터의 식별자는 a로 한다.'입니다. 위 변수는 아직 데이터를 가지고 있지 않기 때문에 undefined
입니다. 여기에 다른 값을 넣게 되면 값에 해당하는 데이터 타입을 가진 변수가 됩니다. 결국 변수는 변경 가능한 데이터가 담긴 그릇(틀)이라고 생각할 수 있습니다. 이제 이 공간에는 숫자나 문자열 등을 담을 수 있게 됩니다.
JavaScript의 데이터 구조를 이해해보자면 대략 아래와 같습니다.
주소 | ... | 1002 | 1003 | 1004 | 1005 | ... |
데이터 |
이름: a 값: |
var a;
변수를 선언하게 되면 메모리에서는 위와 같은 방식으로 공간을 확보하게 됩니다. 이후 사용자가 a에 접근하고자 할 때 컴퓨터는 메모리에서 a라는 이름을 가진 주소를 검색해 해당 공간에 담긴 데이터를 반환합니다.
데이터를 할당하는 방법은 아래와 같습니다.
var a; // 변수 a 선언
a = 'hello'; // 변수 a에 데이터 할당
var a = 'hello'; // 변수 선언과 할당을 동시에
위 두 방법의 결과는 동일합니다. 하지만 실제로 위에서 보이는 것 처럼 a에 값이 'hello'가 들어가지 않습니다. 할당된 데이터 'hello'는 다른 임의의 번지(5004)에 할당되며 a의 실제 값은 5004 번지를 가리키게 됩니다.
이 처럼 할당이 이루어지게 되면 위 표에 1003 영역에 a의 값으로 할당된 데이터의 주소가 들어갑니다.
주소 | ... | 1002 | 1003 | 1004 | 1005 | ... |
데이터 |
이름: a 값: @5004 |
|||||
주소 | ... | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | 'hello' |
왜 컴퓨터는 번거롭게 두번의 할당을 통해서 변수를 저장하는 걸까요? 이유는 (1)데이터 변환을 자유롭게 하기위함과 (2)메모리를 효율적으로 관리하기 위해서 입니다. 구체적으로 JS에서 숫자형 데이터는 64bit(8Byte)의 공간을 차지합니다. 하지만 문자열의 경우 정해진 규격이 없습니다. 따라서 위와 같은 방식을 통해 문제점을 해결한 것입니다. 만약 미리 확보한 공간 내에서만 데이터를 변환한다면 더 많은 공간을 차지하는 데이터에 의해서 확보된 공간을 변환된 데이터 크기에 맞게 늘리는 작업을 해야합니다.(데이터의 공간을 늘리고 다음 번지의 데이터를 뒤로 밀어내야하는 번거로운 작업)
해당 공간이 메모리 상의 맨 마지막에 있었다면 신경쓰지 않아도 되지만 다른 데이터들 사이에 있는 경우 해당 공간 뒤로 모든 데이터를 밀어내고 위치시키는 작업을 하기 때문에 매우 비효율적인 작업(컴퓨터의 연산이 많아짐)이 됩니다. 결국 문자열 데이터의 변환을 처리하기 위해서는 변수와 데이터의 별도의 공간을 주어 효율적으로 저장하는 것이 최적의 방법입니다.
그런데 만약
a = 'hello world'
코드를 추가하면 어떻게 될까요? 만약 문자열의 수정이 일어날 경우 다른 번지에 데이터를 다시 저장하고 그 번지를 가리키게 됩니다.
주소 | ... | 1002 | 1003 | 1004 | 1005 | ... |
데이터 |
이름: a 값: @5005 |
|||||
주소 | ... | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | 'hello' | 'hello world' |
위에서 보는 것처럼 문자열은 변경 시에 무조건 새로운 번지에 새로운 공간을 가지고 변경된 데이터를 저장하게 됩니다.
'Front-End > JavaScript' 카테고리의 다른 글
[JS] 함수선언(Function Declarations) (0) | 2020.01.04 |
---|---|
[JS] 함수표현(Function Expressions) (0) | 2020.01.04 |
[JS] 호이스팅(hoisting) (0) | 2020.01.04 |
[JS] Currying in JavaScript ES6 (0) | 2020.01.01 |
[JS] undefined와 null (0) | 2019.12.29 |