스터디키워드 - 자바스크립트 데이터 타입 (기본형과 참조형의 종류와 차이점)

김주현·2021년 8월 1일
0

[Javascript]

목록 보기
4/16

자바스크립트 데이터 타입

자바스크립트 데이터 타입은 프로그래밍 언어에서 사용 가능한 데이터의 종류를 의미한다. JavaScript의 모든 값은 데이터 타입을 갖게 되는데 ECMAScript(ES6) 기준으로 다음과 같이 크게 2가지의 데이터 타입을 가진다.

  • 원시 타입
    • Number
    • String
    • Boolean
    • Symbol(ES6에 추가, 객체속성을 만드는 데이터 타입)
    • null
    • undefined
  • 참조 타입
    • object
    • array
    • Function
    • RegExp
    • Map
    • 등등...

Primative Type

객체가 아닌 데이터 유형을 말한다.

  • Number
  • String
  • Boolean
  • Symbol(ES6에 추가, 객체속성을 만드는 데이터 타입)
  • null
  • undefined

기본형은 값을 그대로 할당하는 것이다.
메모리상에 고정된 크기로 저장되며, 원시데이터 값 자체를 보관하므로 불변적(변경 불가능한 값)이다.
기본적으로 같은 데이터는 하나의 메모리를 사용한다.(재사용)

var a;          //a는 111번 영역으로
var b = 'abc';  //b는 112번 영역으로
var c = b;      //c는 113번 영역으로
a = 10;
b = false;

변수 a,b,c를 선언하게 되면 우선 변수를 저장할 비어있는 데이터 영역을 확보한다

  • 변수 a는 111번 영역, 변수 b는 112번 영역, 변수 c는 113번 영역으로 해당주소를 확보하고 해당주소를 변수명과 맵핑시킨다

기존 변수 c에 값을 새롭게 할당하려고 하는 경우, 새로운 변수는 별도의 공간을 확보하고 불리언값을 통해 기존 변수에 대입된다. (기본값은 직접적인 비교가 가능하다)

var a;          //a는 001번 영역으로
var b = 'abc';  //b는 002번 영역으로
var c = b;      //c는 003번 영역으로
a = 10;
b = false;
c = 20;         // 새로운값 20할당

1. Boolean

boolean타입은 논리적인 요소를 나타내고, true와 false 만을 값으로 갖는다.

var foo = true;
var bar = false;

// typeof 연산자는 타입을 나타내는 문자열을 반환한다.
console.log(typeof foo); // boolean
console.log(typeof bar); // boolean

boolean타입의 값은 참과 거짓으로 구분되는 조건에 의해 프로그램의 흐름을 제어하는 조건문에서 자주 사용된다.

//예제1
var flag=null;

if(flag){
  console.log('메롱~');
}else{
  console.log('틀렸어');
}
//틀렸어

//예제2
var flag="";

if(flag){
  console.log('메롱~');
}else{
  console.log('틀렸어');
}
//틀렸어

false로 변환되는 undefined,null,0,-0,NaN,""(빈 문자열)은 거짓으로 판정되는(falsy)값이라 부르고, 이 이외의 값들은 참으로 판정되는(truthy)값이라 부른다.

2. Null

null타입은 null만을 유일한 값으로 가진다. 자바스크립트는 대소문자를 구별하므로 null은 Null,NULL등과 다르다.

프로그래밍 언어에서 null은 의도적으로 변수에 값이 없다는 것을 명시할 때 사용한다. 다시말해서, 아무것도 참조하고 있지 않다라는 의미가 담겨 있으며 주로 객체를 담을 변수를 초기화할 때 많이 사용한다.

var foo = 'Lee';
foo = null;      //참조정보가 제거됨

다음과 같이 Document.querySelector()는 조건에 부합하는 HTML요소를 검색할 수 없는 경우, null을 반환한다.

var element = document.querySelector('.myElem');
// HTML 문서에 myElem 클래스를 갖는 요소가 없다면 null을 반환한다.
console.log(element); // null

타입을 나타내는 문자열을 반환하는 typeof연산자로 null값을 연산해보면 null이 아닌 object가 나오게 된다. 이는 자바스크립트의 설계상의 오류이다.

var foo = null;
console.log(typeof foo); // object

따라서 null타입을 확인할때는 typeof연산자를 사용하면 안되고 일치 연산자(===)를 사용하여야 한다.

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

3. Undefined

undefined타입은 undefined만을 유일한 값으로 갖는다.변수선언 이후 값을 할당되지 않았거나 객체의 존재하지 않는 프로퍼티에 접근 했을 경우undefined가 반환된다.

var foo;
console.log(foo);           //undefined
console.log(typeof foo)     //undefined

undefined값은 의도적으로 할당한 값이 아닌 Javascript엔진에 의해 초기화된 값입니다. 의도적으로 값이 없음을 명시하기 위해서 undefined를 할당할 수는 있지만 undefined 본래의 취지와 어긋나고 혼란을 줄 수 있기 때문에 권장하지 않습니다. 그러한 경우엔 null을 대신 할당합니다.

4. Number

단 하나의 값으로 모든 종류의 숫자 타입을 표현한다.
(정수, 부동소수점 수, 무한대, -무한대, NaN(Not a Number))

var integer=10;			//정수
var double=10.12;		//실수
var negative=-20;		//음의 정수
var binary=0b01000001;  //2진수
var octal=0o101;		//8진수
var hex=0x41;			//16진수

console.log(binary);	//65
console.log(octal);		//65
console.log(hex);		//65

console.log(binary == octal);	//true
console.log(octal == hex);		//true

자바스크립트의 숫자 타입은 정수만을 위한 타입이 없고 모든 수를 실수로 처리한다. 정수로 표시된다고 해도 사실은 실수이다.


위에 예시를 통해 서로 값이 다른 모습을 확인 할 수 있다.
그 이유는 자바스크립트 숫자타입의 값이 배정밀도 64비트 부동소수점 형식을 따르기 때문이다.

c나 자바의 경우, 정수와 실수를 구분해서 int,long,float,double 등과 같은 타입으로 정수와 실수를 구분해서 사용하지만 자바스크립트의 경우 모든수를 실수로 처리하기 때문에 하나의 숫자타입만 존재합니다.

추가적으로 3가지 특별한 값들도 표현할 수 있다.

  • infinity : 양의 무한대
  • -infinity : 음의 무한대
  • NaN : 산술연산불가(not-a-number)
var pInf = 10 / 0;    //양의 무한대
console.log(pInf);    //Infinity

var nInf = 10 / -0;   //음의 무한대
console.log(nInf);    //-Infinity

var nan = 1 * 'string'; // 산술 연산 불가
console.log(nan);       // NaN

5. String

문자열(String)타입은 텍스트 데이터를 나타내는데 사용한다.문자열은 0개 이상의 16bit 유니코드 문자(UTF-16)들의 집합으로 작은따옴표(' ')와 큰따옴표(" ")로 생성한다. 변수의 타입은 String으로 나온다.

var str = "string"; // 큰 따옴표
str = 'string';     // 작은 따옴표
str = `string`;     // 백틱(ES6 템플릿 리터럴)

str = "큰 따옴표로 감싼 문자열 내의 '작은 따옴표'는 문자열이다.";
str = '작은 따옴표로 감싼 문자열 내의 "큰 따옴표"는 문자열이다.';

다음과 같이 +연산자를 사용할 수 있습니다.

let longString = "여러 줄에 걸쳐 작성해야 할 정도로 " +
                 "긴 문자열인데 왜 한 줄에 다 적으면 안되냐면 " +
                 "코드를 읽기 힘들어지니까요.";

아니면 역슬래시문자("\")를 각 줄의 맨 끝에 붙여 문자열이 이어진다는 걸 표시할 수도 있다. 뒤에 공백붙이지 않게 주의

let longString = "여러 줄에 걸쳐 작성해야 할 정도로 \
긴 문자열인데 왜 한 줄에 다 적으면 안되냐면 \
코드를 읽기 힘들어지니까요.";

주의할 점은 자바스크립트의 문자열은 C언어와 다르게 변경불가능(immuatable)합니다. 이것은 한번 문자열이 생성되면, 그 문자열을 변경 할 수 없다는 것을 의미합니다.

다음과 같이 변수str에 두개의 문자열을 넣었을 경우

var str = 'Hello';
str='world';

console.log(str)     //world

결과적으로 'Hello'를 수정하여 'world'로 생성한 것이 아닌 첫번째구문 'Hello'를 메모리에 생성하고 두번째 구문인 'World' 또한 메모리에 생성하여 변수str이 'Hello'를 가리키고 있다가 'world'를 가리키도록 변경되었을 뿐이다.
따라서 문자열'Hello' 와 'world'는 모두 메모리에 존재하고 있다.

다음과 같이 문자열은 배열처럼 인덱스를 통해 접근할 수 있다. 이와 같은 특성을 같는 데이터를 유사배열이라고 한다.

var str = 'string';
for (var i=0; i<str.length; i++){
	console.log(str[i]);
}

//문자열을 변경 할 수 없다.
str[0] = 'S';
console.log(str);    //string

str[0] = 'S';처럼 이미 생성된 문자열의 일부 문자를 변경해도 반영되지 않는다.한번 생성된 문자열은 read only로서 변경할 수 없다. 이것을 변경 불가능(immutable)이라고 한다.

그러나 새로운 문자열을 재할당하는 것은 가능하다. 이는 기존 문자열을 변경하는 것이 아니라 새로운 문자열을 새롭게 할당하는 것이기 때문이다.

var str = 'string';
console.log(str);        // string

str = 'String';
console.log(str);        // String

str += ' test';
console.log(str);        // String test

str = str.substring(0, 3);
console.log(str);        // Str

str = str.toUpperCase();
console.log(str);        // STR

6. symbol

심볼(symbol)은 ES6에서 새롭게 추가된 7번째 데이터 타입으로 변경불가능한 원시 타입의 값이다. 심볼은 주로 이름의 충돌 위험이 없는 유일한 객체의 프로퍼티 키(property key)를 만들기 위해 사용한다. 심볼은 symbol함수를 호출해 생성한다. 이때 생성된 심볼 값은 다른 심볼값들과 다른 유일한 심볼 값이다.

// 심볼 key는 이름의 충돌 위험이 없는 유일한 객체의 프로퍼티 키
var key = Symbol('key');
console.log(typeof key); // symbol

var obj = {};
obj[key] = 'value';
console.log(obj[key]); // value

//Symbol()로부터 반환되는 값은 항상 고유합니다.
const s1 = Symbol()
const s2 = Symbol()
const aSymbol_1 = Symbol('a')
const aSymbol_2 = Symbol('a')

console.log(s1 === s2) // false
console.log(aSymbol_1 === aSymbol_2) // false

같은 심볼을 사용하고 싶을땐 다음과 같이 생성하여야 한다.

//방법1
const s1 = Symbol()
const s2 = s1
const aSymbol_1 = Symbol('a')
const aSymbol_2 = aSymbol_1

console.log(s1 === s2) // true
console.log(aSymbol_1 === aSymbol_2) // true

//방법2
const s1 = Symbol.for('mySym')
const s2 = Symbol.for('mySym')

console.log(s1 === s2)    //true

심볼은 기존의 다른 원시타입과는 다르게 new연산자를 통해 Wrapper 객체를 생성할 수 없다.

const str = new String('Hello')
const num = new Number(12)
const sym = new Symbol() // TypeError
//심볼타입은 주로 객체의 고유한 프로퍼티의 값으로 사용하는 목적으로 쓰입니다.

Reference Type

참조타입은 변수에 할당할 때 값이 아닌 데이터의 주소를 저장한다.

  • Object
  • Array
    const로 선언된 변수 배열에 Array.push를 적용할 수 있는 이유는 배열은 참조타입이기 때문에 데이터의 주소를 대입할 수 있기 때문이다.
  • Function RegExp
    문자열에 나타나는 특정 문자조합과 대응시키기 위해 사용되는 패턴이다.
  • Map
  • 등등...

참조형은 기본형 데이터의 집합이다. 참조형 데이터는 값이 지정된 주소값을 할당한다.

var obj3={
    a : [4, 5, 6]
};

객체의 선언은 위와 같이 저장된다.

  • 값이 저장된 주소값을 할당한다
  • 비어있는 데이터 공간을 확보하고, 객체 속 프로퍼티에 대한 공간을 다시 확보한다.
  • 객체의 프로퍼티명과 주소를 매칭하고 확보했던 두번째 주소에 데이터를 할당한다.

    변수를 선언하면 데이터가 담길 공간을 확보하고, 확보된 데이터의 주소값을 가지고 변수면과 매칭시키는 선언과정까지 동일하나, 할당과정에 차이를 가진다.

원시타입 예시1

var a;
a = 10;
var b = 'abc';
b = false;
var c = b;
c = 20;

참조타입 예시1

var obj={
    a:1,
    b:'b'
};
var obj2=obj; //저장된 주소만을 복사
obj2.a=10;    //변수 obj2.a의 값 10으로 변경

참조타입 예시2

var obj3={
  a : [4, 5, 6]
};

참조타입 예시3

obj3.a = ''new"로 할당하게 되면,
1002 주소의 데이터를 new로 변경하고 3001 ~ 3003을 참고하고 있던 링크가 사라지게 된다.
그러면 연결되지 않은 링크들은 가비지 컬렌션(G.C)의 대상이 되어 메모리 회수가 된다.

var obj3={
  a : [4, 5, 6]
};

obj3.a='new'; // 3001,3002,3003 주소의 연결이 끊기게 된다.

✔참고사이트

2개의 댓글

comment-user-thumbnail
2021년 8월 2일

안녕하세요 잠깐 들러봤습니다 :) 주현님 레퍼런스 엄청 자세히 찾아보고 정리 잘 해주셨네요👍👍👍
지금처럼 열심히 공부하시면 좋은 개발자가 되실 것 같습니다👍 빨리 개강날이 되서 뵙기를 기다리겠습니다🙌

1개의 답글