Skip to Content

6장 데이터 타입

JS의 모든 ‘값’은 무조건 데이터 타입을 가진다.

구분데이터 타입설명
숫자 타입 (number)숫자 타입(정수, 실수 구분 X)
문자열 타입 (string)문자열
원시 타입불리언 타입 (boolean)true, false
undefined 타입var 키워드 선언된 변수에 암묵적으로 할당되는 값
null 타입값이 없다는 것을 의도적으로 명시할 때 사용하는 값
symbol 타입EX6에서 추가된 타입
객체 타입객체, 함수, 배열

개발자는 자신이 할당한 값이, 명확히 어떤 의미를 가지는지 타입으로 구별해줘야 함

ex) 숫자 1과 문자열 ‘1’은 엄연히 다르다

6-1. 숫자 타입

  • JS는 int, long, float 없이 하나의 타입만 존재한다.

  • 64비트 부동소수점 형식을 따른다 → 즉, 모든 값을 실수로 처리한다.

    // 모두 number 타입이다 var integer = 10; var double = 10.12; var negative = -20; //숫자 타입은 모두 실수로 처리된다. console.log(1 === 1.0); //true console.log(4 / 2); //2 console.log(3 / 2); //1.5
  • 모두 64비트 부동소수점 형식의 2진수로 저장된다 → JS는 모두 해석을 10진수로 한다.

    var binary= 0b0100001;//2진수 var octal = 00101; // 8진수 var hex = 0×41; // 16진수 console.log(binary); //65 console.log(octal); //65 console.log(hex); //65 console.log(binary === octal); //true console.log(octal === hex); // true
  • 숫자 타입의 3가지 특별한 값 표현

    • NaN : 산술 연산 불가(not-a-number)
      • JS는 대소문자를 구별하기에, 무조건 NaN으로 정확하게 작성해줘야 한다.
    • -Infinity : 양의 무한대
    • Infinity : 음의 무한대
    console.log(10 / 0); //Infinity console.log(10 / -0); //-Infinity console.log(1 * 'String'); //NaN

6-2. 문자열 타입

텍스트 데이터를 나타나는데 사용

  • 0개 이상의 16비트 유니코드 문자(UTF-16)의 집합으로 전 세계 대부분의 문자 표현 가능

  • 작은따옴표(’’), 큰 따옴표(””) 또는 백틱(````)으로 텍스트를 감싼다. → 키워드, 식별자와 같은 토큰과 구분하기 위해서 따옴표를 사용한다.

    //문자열 타입 var string; string = '문자열'; //작은따옴표 string = '문자열'; //큰따옴표 string = `문자열`; //백틱 string = '작은따옴표로 감싼 문자열 내의 "큰따옴표"는 문자열로 인식된다.'; string = "큰따옴표로 감싼 문자열 내의 '작은따옴표'는 문자열로 인식된다.";
  • 원시 타입이며, 변경 불가능한 값이다! (이후에 더 자세히 알아보자)

6-3. 템플릿 리터럴

ES6부터 새로 도입된 문자열 표기법이다.

  • 멀티라인 문자열, 표현식 삽입, 태그드 템플릿 등 편리한 문자열 처리 기능을 제공한다.
  • 백틱(````)을 사용해서 표현하는 방법이다 -> 런타임에 일반 문자열로 변환되어 처리된다
    var template = `Template literal`; console.log(template); //Template literal

6-3-1. 멀티라인 문자열

  • 일반 문자열 방식 : 줄바꿈이 허용되지 않아서, 백슬래시(\)로 시작하는 이스케이프 시퀀스를 사용해야 한다.

    // 그냥 개행 추가 -> 오류 var str = 'Hello worrld.'; // SyntaxError: Invalid or unexpected token // 이스케이프 시퀀스 활용 var template = '<ul>\n\t<li><a href="#">Home</a></li>\n</ul>'; console.log(template);
  • 멀티라인 문자열 방식 : 이스케이프 시퀀스 사용하지 않고도 사용 가능하다

    var template = `<ul> <li><a href="#">Home</a></li> </ul>`; console.log(template);
    //출력 결과 <ul> <li> <a href="#">Home</a> </li> </ul>

6-3-2. 표현식

  • 일반 문자열 방식 : 문자열 연산자 +를 사용해 연결 가능하다.

      • : 피연산자 중 하나 이상인 경우에 문자열 연결 연산자로 동작한다
    var first = 'Ung-mo'; var last = 'Lee'; // ES5 : 문자열 연결 console.log('My name is ' + first + ' ' + last + '.'); //My name si Ung-mo Lee.
  • 표현식 삽입 방식 : 연산자 없이, ${ }를 활용해 문자열을 연결할 수 있다.

    • 더 가독성이 좋다!

      var first = 'Ung-mo'; var last = 'Lee'; // ES6 : 문자열 연결 console.log(`My name is ${first} ${last}.`); //My name si Ung-mo Lee.
    • 반드시 템플릿 리터럴 내에서 사용해야 한다.

      • 연산이 아닌, 문자열로 취급될 수 있다
      console.log(`1 + 2 = ${1 + 2}`); // 1 + 2 = 3 console.log('1 + 2 = ${1 + 2}'); // 1 + 2 = ${1 + 2}

6-4. 불리언 타입

true, false 값을 말한다. 그 이외의 값은 없다.

var foo = true; console.log(foo); // true foo = false; console.log(foo); // false

6-5. undefined 타입

undefined 타입의 값은 undefined가 유일하다

  • undefined : 값이 할당된 적이 없다는 것을 나타내는 값 ⇒ 값 자체가 없다는 것을 명시하고 싶을 때는 null을 사용해야 한다!

  • var 키워드로 선언한 변수 : 암묵적으로 undefined로 초기화된다.

    var foo; console.log(foo); // undefined
    • 변수 선언에 의해 메모리 공간이 확보된다.
    • 처음 할당이 이루어질 때까지 쓰레기 값으로 두지 않고 JS 엔진이 undefined로 초기화한다.

6-6. null 타입

null 타입의 값은 null이 유일하다.

  • null : 값 자체가 없다는 것을 명시하고 싶을 때 사용

  • JS는 대소문자를 구별하기에, 무조건 null로 정확하게 작성해줘야 한다.

  • 변수에 null을 할당한다는 의미 : 변수가 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미 ⇒ 이전에 할당되어 있던 값을 명시적으로 삭제하는 역할이기도 하다

    var foo = 'Lee'; // 이전에 참조하던 값을 더이상 참조하지 않는다 // 이전에 참조하던 값을 아무도 참조하지 않는다면 가비지 콜렉션을 수행할 것이다. foo = null;

6-7. symbol 타입

ES6에서 추가된 7번째 타입, 변경 불가능한 원시 타입의 값

⇒ 다른 값과 중복되지 않은 유일무이한 값을 나타낸다.

  • 주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용한다.

  • Symbol 타입의 값은, Symbol 함수를 활용해 생성한다.

    • 이때 생성된 값은 외부에 노출되지 X, 유일무이
    // 심벌 값 생성 var key = Symbol('key'); console.log(typeof key); // symbol // 객체 생성 let obj = {}; // 이름이 충돌할 위험이 없는 유일무이한 값인 심벌을 프로퍼티 키로 사용한다. obj[key] = 'value'; console.log(obj[key]); //value

6-8. 객체 타입

지금까지 살펴본 원시 타입 이외의 것들은 모두 객체 타입이다.

JS를 이루고 있는 거의 모든 것이 객체로 취급된다. (중요)

6-9. 데이터 타입의 필요성

그렇다면 데이터 타입을 구분하는 것은 왜 필요한 것일까?

  • 값을 저장할 때 확보해야 하는 메모리 공간의 크기를 결정하기 위해
  • 값을 참조할 때 한 번에 읽어 들여야할 메모리 공간의 크기를 결정하기 위해
  • 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해

아래 score에 숫자 값 100을 저장하는 예제를 기준으로 살펴보자.

var score = 100;

6-9-1. 데이터 타입에 의한 메모리 공간의 확보와 참조

값을 메모리에 저장하고 참조할 때, 확보할 공간의 크기를 정해 낭비와 손실 없이 저장할 수 있는지 알아야 한다.

ex) 100을 저장할 때 타입 정보를 기준으로 다음과 같은 과정을 거친다.

  1. 리터럴 100을 숫자 타입의 값으로 해석
  2. 숫자 타입이기에 8바이트 공간 확보
  3. 100을 2진수로 저장
  4. 해당 score 값을 참조하는 경우, JS엔진은 숫자 타입을 인식한다.
  5. 숫자 타입의 메모리 공간의 크기가 8바이트이기에 8바이트 만큼 읽어들인다.

6-9-2. 데이터 타입에 의한 값의 해석

모든 값은 메모리에 2진수, 즉 비트의 나열로 저장될텐데

읽어 들인 값은 어떻게 알맞은 방법으로 해석하는가? → 데이터 타입에 의해 해석한다.

6-10 동적 타이핑

변수의 타입은 어떻게 결정되는가?

6-10-1. 동적 타입 언어와 정적 타입의 언어

정적 타입 언어(C, java, kotlin, go …)

  • 명시적 타입 선언 방식 → 변수의 데이터 타입을 변수를 선언하는 시점, 즉 사전에 선언해야 한다.
// c 변수에는 1바이트 정수 타입의 값 (-128 ~ 127)만 할당할 수 있다. char c; // num 변수에는 4바이트 정수 타입의 값 (-2,124,483,648 ~ 2,124,483,647)만 할당할 수 있다. int num;
  • 변수의 타입을 변경할 수 없고, 최초로 선언한 타입에 맞는 값만 할당 가능하다.
  • 컴파일 시점에 타입 체크를 수행한다.
    • 만약 통과하지 못 하면? 에러 발생, 프로그램 실행 자체를 막는다.
  • 타입의 일관성을 강제하기에 더욱 안정적인 코드 구현 → 런타임에 발생하는 에러가 줄어든다.

동적 타입 언어 (JS, python, PHP, Ruby …)

  • 변수를 선언할 때 타입을 선언하지 않고, var / let / const라는 키워드를 사용해 선언한다.

  • 정해진 타입이 아닌, 상황에 따라 자유롭게 값을 할당할 수 있다.

  • 즉, 변수의 타입은 값에 따라 동적으로 결정된다.

    var foo; console.log(typeof foo); //undefined foo = 3; console.log(typeof foo); //number foo = 'Hello'; console.log(typeof foo); //string foo = true; console.log(typeof foo); //boolean foo = null; console.log(typeof foo); //object foo = Symbol(); //심벌 console.log(typeof foo); //symbol foo = {}; //객체 console.log(typeof foo); //object foo = []; //배열 console.log(typeof foo); //object foo = function () {}; //함수 console.log(typeof foo); //function
    • typeof 연산자 : 해당 연산자 뒤에 위치한 피연산자의 데이터 타입을 문자열로 반환하는 함수
  • 기본적으로 변수는 타입을 갖지 않고, 값은 타입을 가진다.

6-10-2. 동적 타입 언어와 변수

동적 타입 언어는 유연성은 높지만 신뢰성은 떨어진다!

  • 동적 타입의 특징 :
    • 데이터 타입에 대해 무감각해질 정도로 편리함
    • 변수의 타입이 고정되어 있지 않고 동적으로 변하는 동적 타입 언어의 변수는 값의 변경에 의해 타입도 언제든지 변경될 수 있다
      • 복잡한 프로그램에서는 변화하는 변수 값을 추적하기 어려울 수 있다.
    • 값을 확인하기 전에는 타입을 확신할 수 없다.
    • 개발자의 의도와는 상관없이 자바스크립트 엔진에 의해 암묵적으로 타입이 자동으로 변환되기도 한다.
      • 즉, 숫자 타입의 변수일 것이라고 예측하지만 사실은 문자열 타입의 변수일 수도 있다는 말
  • 변수를 사용할 때 주의할 사항
    • 변수는 꼭 필요한 경우에 한해 제한적으로 사용해야 한다.
    • 변수의 유효 범위(스코프)는 최대한 좁게 만들어 변수의 부작용을 억제해야 한다.
    • 전역 변수는 최대한 사용하지 않도록 한다.
    • 변수보다는 상수를 이용해 값의 변경을 억제한다.
    • 변수 이름은 변수의 목적이나 의미를 파악할 수 있도록 네이밍한다.

⇒ 동작하는 코드가 아닌, 가독성이 좋은 코드가 좋은 코드다 라는 것을 잊지 말아야 한다!

Last updated on