6장 데이터 타입(Data type)
데이터 타입 = 값의 종류
자바스크립트의 모든 값은 데이터 타입을 갖는다.
자바스크립트(ES6)에는 총 7개의 데이터 타입이 있다.
- 원시 타입 (primitive type)
a. 숫자 number
b. 문자열 string
c. 불리언 boolean
d. undefined
e. null
f. 심벌 symbol
- 객체 타입 (object/ reference type)
a. 객체, 함수, 배열 등
6.1 숫자 타입
** C, Java에서는 정수/실수를 구분하여 int, long, float, double 등 다양한 숫자타입을 제공한다.
- 자바스크립트에서는 모든 수를 실수로 처리(배정밀도 64비트 부동소수점 형식의 값)
console.log(0b01000001); // 2진수
console.log(0o101); // 8진수
console.log(0x41); // 16진수
=> 65
// 숫자타입은 모두 실수로 처리된다.
console.log(1 === 1.0); // true
숫자 타입의 특별한 값 3가지
- 양의 무한대 Infinity
- 음의 무한대 -Infinity
- 산술 연산 불가 NaN (not-a-number)
console.log(10 / 0); // Infinity
console.log(10 / -0); // -Infinity
console.log(1 * "string"); // NaN
!! 자바스크립트는 대소문자를 구별하기 때문에 NaN 사용시 주의
6.2 문자열 타입
= 텍스트 데이터
- 키워드나 식별자 같은 토큰과 구분하기 위해서 작은따옴표(''), 큰따옴표(""), 백틱(``)을 사용한다.
- 자바스크립트의 문자열은 원시 타입이며, 변경 불가능한 값(immutable value)이다.
** C는 문자열을 문자의 배열로 표현하고, 자바는 객체로 표현한다.
6.3 템플릿 리터럴 (template literal)
- ES6부터 도입된 새로운 문자열 표기법
- 백틱(``) 사용
1. 멀티라인 문자열 (multi-line string)
- 일반 문자열 내에서 줄바꿈(개행) 등의 공백(white space) 을 표현하려면 백슬래시( \ )로 시작하는 이스케이프 시퀀스를 사용해야 한다.
- 일반 문자열과 달리 템플릿 리터럴(백틱,``) 내에서는 이스케이프 시퀀스를 사용하지 않고도 줄바꿈이 허용되며, 모든 공백도 있는대로 적용된다.
이스케이프 시퀀스 종류
\0 : null
\v : 백스페이스
\n : 개행, 다음 행으로 이동
\r : 개행, 커서를 처음으로 이동
\t : 탭(수평)
\v : 탭(수직)
등등..
라인 피드와 캐리지 리턴
정의: 텍스트의 한 줄이 끝남을 표시하는 개행(newline) 문자
- 라인 피드(line feed): \n , 커서를 정지한 상태에서 종이 한 줄을 올리는 것, 일반적으로 사용
- 캐리지 리턴(carriage return): \r , 종이를 움직이지 않고 커서를 맨 앞줄로 이동하는 것
2. 표현식 삽입 (expression interpolation)
- 문자열은 문자열 연결 연산자(+)를 사용해 연결할 수 있다.
- 표현식 삽입은 ${ } 로 표현식을 감싼다. 이 때 표현식의 평가 결과는 무조건 문자열 타입이 된다.
- 표현식 삽입은 반드시 템플릿 리터럴 내에서 사용해야 한다.
let first = 'Leah';
let last = 'Lee';
// 문자열 연산자 사용
console.log('My name is ' + first + ' ' + last + '.');
// 표현식 삽입 사용
console.log(`My name is ${first} ${last}.`);
3. 태그드 템플릿 (tagged template)
- 템플릿 리터럴의 발전된 형태로써, 함수 형태로 사용할 수 있다.
- 이 문법은 문자열에서 name, age 와 같은 변수(동적 데이터)들과 "Hi," "my name is" 과 같은 정적인 문자열(정적 데이터)을 구분지을 수 있다.
function transform(staticData, ...dynamicData) {
console.log(staticData); // ["Hi, ", "my name is", "."]
console.log(dynamicData); // ["xx", 30]
}
transform`Hi, ${age} my name is ${name}.`;
- 함수 호출 방식이 transform`` 형태
첫번째 파라미터 : 정적 데이터
나머지 파라미터 : 동적 데이터
특징 :
타입에 상관없이 Function, Number, Array, Object 등을 전달하고 이를 실행할 수 있게 된다.
ex. age 값의 타입은 String 이 아닌 Number 형태로 타입이 유지된다.
6.4 불리언 타입
- 논리적 참과 거짓을 나타내는 값인 true와 false
6.5 undefined 타입
- 변수 선언에 의해 확보된 메모리 공간은 처음 할당 전까지 빈 상태가 아닌 undefined로 초기화된다.
- 자바스크립트 엔진이 변수를 초기화 할 때 사용하는 값 = 값을 할당하지 않은 변수
- 개발자가 변수에 값이 없다는 것을 명시하고 싶을 때는 undefined 가 아닌 null을 할당한다.
선언(declaration)과 정의(definition)
- undefined = "정의되지 않은" = 변수에 값을 할당하여 변수의 실체를 명확히 알지 못한다.
- 변수는 '선언한다'라고 표현하고, 함수는 '정의한다'라고 표현한다.
6.6 null 타입
- null은 변수에 값이 없다는 것을 의도적으로 명시(의도적 부재, intentional absense)할 때 사용한다.
- 변수에 null을 할당하는 것은 변수가 이전에 할당되어 있던 값에 대한 참조를 제거하는 것을 의미한다.
- 자바스크립트 엔진은 누구도 참조하지 않는 메모리 공간에 대해 가비지 콜렉션을 수행한다.
- 함수가 유효한 값을 반환할 수 없는 경우 명시적으로 null을 반환하기도 한다.
6.7 심벌(symbol) 타입
= 변경 불가능한 원시 타입의 값
- 다른 값과 중복되지 않는 유일무이한 값이기 때문에 객체의 유일한 프로퍼티 키를 만들기 위해 사용한다.
- 심벌은 심벌 함수를 호출해 생성한다.
// 심벌 값 생성
var key = Symbol('key');
console.log(typeof key); // symbol
// 이름이 충돌할 위험이 없는 유일무이한 값인 심볼을 프로퍼티 키로 사용
var obj= {};
obj[key] = 'value';
console.log(obj[key]); // value
6.8 객체 타입
- 자바스크립트를 이루고 있는 거의 모든 것이 객체다.
6.9 데이터 타입의 필요성
1. 데이터 타입에 의한 메모리 공간의 확보와 참조
- 컴퓨터는 값을 저장하기 위해 메모리 공간을 확보한 다음, 확보된 메모리에 값을 저장한다.
- 자바스크립트 엔진은 데이터 타입, 즉 값의 종류에 따라 정해진 크기의 메모리 공간을 확보한다.
- 메모리 공간의 크기 = 메모리 셀의 개수(바이트 수)
var score = 100;
- 리터럴 100을 숫자 타입의 값으로 해석하고 숫자 타입의 값 100을 저장하기 위해 8바이트의 메모리 공간을 확보하여 2진수(배정밀도 64비트 부동소수점 형식)로 저장한다.
- 값을 참조하는 경우, 식별자 score를 통해 숫자 타입의 값 100이 저장되어 있는 메모리 공간의 선두 메모리 셀의 주소를 찾아간다.
- score 변수를 숫자 타입으로 인식하여 참조시 8바이트 단위로 메모리 공간에 저장된 값을 읽어 들인다.
** 심벌 테이블 : 컴파일러 또는 인터프리터는 심벌 테이블이라고 부르는 자료 구조를 통해 식별자를 키로 바인딩된 값의 메모리 주소, 데이터 타입, 스코프 등을 관리한다.
2. 데이터 타입에 의한 값의 해석
- 모든 값은 데이터 타입을 가지며 메모리에 2진수, 즉 비트의 나열로 저장된다.
- 메모리에 저장된 값은 데이터 타입에 따라 다르게 해석될 수 있다. ex. 0100 0001 = 65 = 'A'
데이터 타입이 필요한 이유 3가지
- 값을 저장할 때 확보해야 하는 메모리 공간의 크기를 결정하기 위해
- 값을 참조할 때 한 번에 읽어 들여야 할 메모리 공간의 크기를 결정하기 위해
- 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해
6.10 동적 타이핑
1. 동적 타입 언어와 정적 타입 언어
정적 타입(static/strong type) 언어
- C, C++, Java, Kotlin, Go, Haskell, Rust, Scala 등
- 명시적 타입 선언(explicit type declaration)
: 변수를 선언할 때 변수에 할당할 수 있는 값의 종류, 즉 데이터 타입을 사전에 선언해야 한다.
- 변수의 타입을 변경할 수 없으며, 변수에 선언한 타입에 맞는 값만 할당할 수 있다.
- 컴파일 시점에 타입 체크(선언한 데이터 타입에 맞는 값을 할당했는지 검사하는 처리)를 수행한다.
- 통과하지 못했을 경우 에러를 발생시키고 프로그램 실행 자체를 막는다.
동적 타입(dynamic/weak type) 언어
- Javascript, Python, PHP, Ruby, Lisp, Perl 등
- 타입 추론(type inference) : 자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정된다.
- 동적 타이핑(dynamic typing) : 재할당에 의해 변수의 타입은 언제든지 동적으로 변할 수 있다.
- 기본적으로 변수는 타입을 갖지 않지만, 값은 타입을 갖기 때문에 변수에 할당되어 있는 값에 의해 변수의 타입이 동적으로 결정된다.
2. 동적 타입 언어와 변수
- 동적 타입 언어는 유연성은 높지만 신뢰성은 떨어진다.
- 변수는 값의 변경에 의해 타입도 언제든지 변경될 수 있다.
변수를 사용할 때 주의할 사항 5가지
- 변수는 꼭 필요한 경우에 한해 제한적으로 사용한다.
- 변수의 유효 범위(스코프)는 최대한 좁게 만들어 변수의 부작용을 억제해야 한다.
- 전역 변수는 최대한 사용하지 않도록 한다.
- 변수보다는 상수를 사용해 값의 변경을 억제한다.
- 변수 이름은 변수의 목적이나 의미를 파악할 수 있도록 네이밍한다.
가독성이 좋은 코드가 좋은 코드다.