본문 바로가기
Dev. Handbook/Javascript

[JavaScript] 데이터 타입(data type)과 형 변환(Type Conversion), Implicit coercion vs Explicit coercion

by breezyday 2023. 2. 25.

1. JavaScript 데이터 타입

1.1 동적 타입(dynamic type)

JavaScript(JS)는 느슨한 타입(loosely typed)동적(dynamic) 언어다.

JS의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당(및 재할당)이 가능하다.

let foo = 42 // number
foo = 'barr' // String
foo = true   // boolean

1.2 데이터 타입의 종류

JS에서 데이터 타입은 원시 값(Primitive values)객체(Object)로 나뉜다.

 

원시 값(Primitive values)
- 객체(Object)를 제외한 모든 타입은 불변 값(immutable value : 변경할 수 없는 값)이다. 
- JS에서는 String도 원시 값으로 불변 값이다.

 

Type typeof return value Object wrapper
Null "object" N/A
Undefined "undefined" N/A
Boolean "boolean" Boolean
Number "number" Number
BigInt "bigint" BigInt
String "string" String
Symbol "symbol" Symbol

 

객체(Object)
- 컴퓨터에서 객체란 식별자(identifier)로 참조할 수 있는 메모리 상의 값이다.
- JS에서 객체는 변경 가능한 유일한 값이다.
- JS에서 함수(function)는 호출 가능한 추가 기능이 있는 객체이기도 하다. 반대로 말하면 함수는 '호출이 가능함'을 제외하면 일반적인 객체이다.

2. 형 변환 [Type Conversion]

JS에서 데이터 타입(형)은 변환될 수 있다. 개발자가 의도적으로 타입을 변환하는 것명시적 타입 변환(Explicit coercion) 혹은 타입 캐스팅(Type Casting)이라고 한다. JS의 엔진에 의해 자동으로 타입이 변환되는 것묵시적 타입 변환(Implicit coercion) 혹은 강제 타입 변환(Type coercion)이라고 한다.

2.1 묵시적 타입 변환 (implicit coercion, type coercion)

JS 엔진이 표현식(expression)을 평가할 때, 콘텍스트(context)를 참고하여 묵시적 타입 변환을 실행한다.

즉 JS 엔진은 표현식의 해석 순서와 연산자에 의해 묵시적 타입 변환을 시도하고 표현식을 실행한다.

묵시적 타입 변환은 정확하게 이해하고 있지 않으면 원치 않는 형 변환이 일어날 수 있으므로 주의해서 사용해야 한다.

숫자와 '+' 연산자

숫자(numeric value)와 문자열(string value)이 '+' 연산자와 함께 사용되는 경우 JS는 숫자를 문자열로 변환하여 처리한다.

console.log('this is '  + '1'); // 'this is 1'
console.log('5' + 2); // '52'

const a = '6';
const b = 2;
console.log(a + b); // '62'

숫자와 '+'를 제외한 산술 연산자

숫자와 '+'를 제외한 다른 산 연산자를 사용하는 경우 JS는 문자열(숫자 표현)을 숫자로 변환하여 처리한다.

console.log('this is '  + '1'); // 'this is 1'
console.log('this is ' - '1'); // NaN
console.log('this is ' * '1'); // NaN
console.log('this is ' / '1'); // NaN
console.log('this is ' % '1'); // NaN

console.log('5' + 2); // '52'
console.log('5' - 3); // 2
console.log('5' * 3); // 15
console.log('5' / 3); // 1.6666666666666667
console.log('5' % 3); // 2

const a = '6';
const b = 2;
console.log(a + b); // '26'
console.log(a - b); // 4
console.log(a * b); // 12
console.log(a / b); // 3
console.log(a % b); // 0

숫자가 아닌 문자열과 문자열이 아닌 다른 데이터 타입인 경우에는 아래와 같이 변환된다.

// 숫자
console.log(1 - '1');   // 0

// 숫자가 아닌 문자열
console.log(1 - '');    // 1 : ''=>0
console.log(1 - 'str'); // NaN : str=>NaN

// 다른 데이터 타입
console.log(1 + true);  // 2 : true=>1
console.log(1 + false); // 1 : false=>0

console.log(1 + null);     // 1 : null=>0
console.log(1 + undefined) // NaN : undefined=>NaN

문자열과 '+' 연산자

표현식에 문자열이 포함되어 '+' 연산자와 함께 사용되면 문자열이 아닌 나머지 값들을 모두 문자열로 변환하여 문자열 연산을 수행한다.

// 
0 + ''        // '0'
-0 + ''       // '-0'
NaN + ''      // 'NaN'
Infinity + '' // 'Infinity'

// boolean
true + ''     // 'true'
false + ''    // 'false'

// null
null + ''     // 'null'

Boolean

표현식에 조건식이 포함되어 있으면 JS는 boolean 타입이 아닌 값Truthy 값(참으로 인식할 값) 또는 Falsy 값 (거짓으로 인식할 값)으로 구분한다. 

// Falsy 값
0, -0
undefined
null
NaN
''

console.log(Boolean(1));         // true
console.log(Boolean(0));         // false
console.log(Boolean(undefined)); // false
console.log(Boolean(null));      // false
console.log(Boolean(NaN));       // false
console.log(Boolean(''));        // false
console.log(Boolean('abc'));     // true

Equality 연산자

표현식에 동등 연산자와 비교 연산자가 있다면 JS는, 서로 다른 타입을 비교할 경우, 문자열이 아닌 데이터 타입은 비교연산자, '==', '!=' 연산자는 경우는 숫자로 변환하여 비교하고 '===', '!==' 연산자변환하지 않고 비교한다.

console.log(0 >= '')     // true   ''=>0
console.log(0 >= '1')    // false
console.log(10 < '11')   // true
console.log(10 > 'aa')   // false  'aa'=>NaN

console.log(true == 1);   // true  true'=>1
console.log(true === 1);  // false
console.log(false == 0);  // true  false=>0
console.log(false === 0); // false

console.log('true' == 1); // false 'true'=>NaN
console.log(10 == '10')   // true  '10'=>10

2.2  명시적 타입 변환 (explicit coercion, type coercion)

문자열 타입으로 변환

// 1. String 생성자
const a1 = String(1)    // '1'
const b1 = String(NaN)  // 'NaN'
const c1 = String(true) // 'true'

// 2. Object.prototype.toString() 
const a2 = (1).toString()    // '1'
const b2 = (NaN).toString()  // 'NaN'
const c2 = (true).toString() // 'true'

// 3. 묵시적 변환 활용
const a2 = 1 + ''    // '1'
const b2 = NaN + ''  // 'NaN'
const c3 = true + '' // 'true'

숫자 타입으로 변환

// 1. Number 생성자
const a1 = Number('1');    // 1
const b1 = Number(false);  // 0

// 2. parseInt, parseFloat 함수 (문자열만 변환 가능)
const a2 = parseInt('1');      // 1
const b2 = parseFloat('10.12') // 10.12

// 3. '+' 단항 연산자
const a3 = +'1';     // 1
const b3 = +true;    // 1

// 4. '*' 산술 연산자
const a4 = '1' * 1   // 1
const b4 = false * 1 // 0

Boolean 타입으로 변환

// 1. Boolean 생성자 함수
// 문자열
const a1 = Boolean('a');  // true
const b1 = Boolean('');   // false
// 숫자
const c1 = Boolean(0);    // false
const d1 = Boolean(1);    // true

const e1 = Boolean(NaN);       // false
const f1 = Boolean(Infinity)); // true
// null, undefined
const g1 = Boolean(null);      // false
const h1 = Boolean(undefined); // false

// 2. '!' 부정 연산자 두번 사용
const a2 = !!'a'   // true
const c2 = !!0     // false
const e2 = !!NaN   // false
const g2 = !!null  // false

 

 

 

 

TMI

mdn에서 한글을 지원하는 것은 고마운 일이지만 한국어 버전은 영문 버전과 달리, 가끔은 단어와 문맥이 이해하기 힘든 번역이 있습니다. 가장 큰 차이점은 한국어 버전에서는 일부 내용이 누락되어 있습니다.

 

영문이 읽기 쉬운 것은 아니지만, 원래 사용하고 있는 용어가 있으므로 원어를 이해하고 있다면 좀 더 정확하게 이해할 수 있습니다. 번역된 용어도 알아두면 좋지만 먼저 영어로 된 용어를 익혀두는 게 더 좋다고 생각합니다. 이 점은 다른 해외의 리소스를 찾아볼 때 좀 더 용이합니다. 

참고

https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures

https://poiemaweb.com/js-type-coercion

https://jihyehwang09.github.io/2019/04/05/33-js-type-coercion/

 

댓글