자바스크립트(javascript) - 타입(유형), 형, 변환 개념잡기
순번 | 링크페이지 아래 제목을 클릭하면 해당 링크페이지로 이동 됩니다. |
1 | JS - 형 변환에 대하여 - (1) |
2 | JS - 형 변환에 대하여 - (2) |
3 | JS - 형 변환에 대하여 - (3) |
4 | JS - 형 변환에 대하여 - (4) |
5 | JS - 형 변환에 대하여 - (5) |
6 | JS - 형 변환에 대하여 - (6) |
JS - 형 변환에 대하여 (1) ~ (4)에서 얘기했던
명시적, 암시적으로 형 변환 얘기했던 부분들을
이번에는 좀더 많은 예제로 알아보자.
▶ 명시적 형 변환
💻 문자열(String) ↔ 숫자(Number)
가장 기본적인 형 변환부터 봐보자.
var num = 100;
var stringNum = String(num);
var str = '3.14';
var strNum = Number(str);
console.log(stringNum); // "100"
console.log(strNum); // 3.14
String()은 이전에 설명한 ToString 작업의 규칙을 사용하여 다른 값에서 기본 문자열 값으로 강제 변환한다.
Number()는 이전에 설명한 ToNumber 작업의 규칙을 사용하여 숫자 값으로 강제 변환한다.
이렇게 문자를 숫자로 형 변환하기 위해 String(), Number() 사용하는 것을 명시적으로 강제 형 변환이라 한다.
이제 다른 형태로 봐보자.
var num = 100;
var stringNum = num.toString();
var str = '3.14';
var strNum = +str;
console.log(stringNum); // "100"
console.log(strNum); // 3.14
toString() 이라는 건 형 변환에 대하여 - (2) 이글에서 설명했듯이 문자열로 반환을 해주는 건데,
이 toString() 메서드는 객체, 배열, number, date, Boolean 등등 여러 개체들이 가지고 있는 메서드이다.
그래서 num 변수에 toString()을 이용하여 문자열로 만든다.
이제 처음 본 다음 걸 봐보자. +str 이게 어떻게 형 변환이 되어서 3.14 가 되었는지 알아보자.
+ 연산자의 단항 연산자 형식이다.
이 연산자는 숫자와 숫자의 덧셈, 문자열은 연결을 수행하는데
단항 + 연산자는 해당 피연산자(str)에 대하여 숫자 값으로 명시적으로 강제 변환한다.
그래서 str은 "3.14"라는 문자열이지만 str 변수 앞에 + 연산자를 붙이는 것만으로도
숫자로 형 변환이 일어난다.
사실 나도 이 부분에 대해서 공부하면서 느낀 점이 있긴 한데...
문자열의 숫자 ex) "100" 이런 문자열에 + 연산자만 붙이면 강제로 숫자로 형 변환된다는 것을
나도 처음 알았다. 사실 이렇게 쓰이는 건 개발하면서도 보질 못했다.
이 부분에 대해서 왜 이게 명시적인 형 변환이냐?라고 생각이 들 수도 있는데,
만약 나 자신이 + 연산자를 붙여서 형 변환이 일어난다고 알고 있다면 그리고 이렇게 꾸준히
개발을 해왔다면 이건 명시적 관점에서 생각해도 된다. 왜냐하면 나 자신이 알고 사용했고,
형 변환을 시키기 위해 내가 한 행동이기 때문에 +라는 연산자를 직접 사용하므로 써
숫자로 형 변환을 시켰기 때문이다. 하지만 만약 팀 프로젝트에서 이렇게 사용한다면?
나같이 이렇게 글을 남기면서 이런 형태의 형 변환을 처음 겪어본 사람이라면?
많은 혼란을 야기시킬 것이다.
예)
var str = 'ab';
str += 'c';
str += 'd';
var num = '100';
num = +num;
console.log(num);
개발을 하다 보면 문자열을 계속 더하는 코드는 많이 사용을 한다...
+= 이런 연산을 이용해서 글자를 합치거나 많이 사용한다.
그런데 = + 이렇게 해서 문자열 숫자를 숫자로 형 변환했다...
이거는 비슷하기도 하며, 암튼 이러한 정확한 개념이 없을 때문 진짜 혼란스러울 거 같다.
그러므로 이러한 형태의 형 변환은 사용하지 말자.
그냥 개념적으로 이렇게도 형 변환이 되는구나....라고 알아두기만 하자.
명시적으로 형 변환할 때는?Number(), String() 이렇게 이용을 하자.
💻 parseInt 를 사용 한 형 변환 ( 문자열 ↔ 숫자 )
parseInt 메서드로 문자열에서 숫자로 명시적 형 변환을 해보자.
Number()로 진행했던 부분과 무엇이 다른지 확인해보자.
var num_1 = "100n";
var num_2 = "100";
console.log(parseInt(num_1)); // 100
console.log(parseInt(num_2)); // 200
console.log(Number(num_1)); // NaN
console.log(Number(num_2)); // 100
parseInt() 메서드로 형 변환했을 때 이상하게도 문자열이 껴있는 "100n"을 형 변환했더니...
말도 안 되게... 100으로 형 변환이 되었다.
Number() 메서드는 바로 NaN이라는 결과를 줬는데 말이다.
그래서 혹시나 해서 다르게 실험 테스트를 했다.
var num_1 = "1n00";
var num_2 = "11n00";
var num_3 = "n100";
console.log(parseInt(num_1)); // 1
console.log(parseInt(num_2)); // 11
console.log(parseInt(num_3)); // NaN
결과를 봐보니 숫자와 문자가 합쳐진 문자열에서 parseInt로 형 변환을 시도할 때,
첫 문자열이 숫자이면 변환을 시도를 시작하지만 그다음에 문자열이 나오면 바로 끊어버린다.
즉, 문자열이 나오기 전까지의 숫자까지 형 변환을 한다.
그래서 마지막 num_3을 확인해 봤을 때, 첫 문자열이 n이라 NaN이라는 결과 값이 나왔다.
그리고 좀 더 이 parseInt에 대해서 정보를 찾아보니...
이 parseInt() 메서드 형 변환은 바로 숫자로 형 변환을 하는 게 아니라 parseInt() 메서드가 동작하는 순간부터
해당 값이 문자열인지 아닌지 판별하고 그다음 문자열이 아니면 이 parseInt() 메서드란 놈 자체가
알아서 ToString 규칙으로 알아서 문자열로 바꾸고, 그다음 강제적으로 숫자로 바꾼다고 한다.
이렇게 프로그램이 자기 맘대로 ToString 규칙을 사용해서 암시적으로 바뀌는 건 안 좋다고 한다.
예로 들자면 내가 어떤 유형으로 형 변환을 시도했는데 결과가 내가 형 변환을 시도했던 결과가 나온 게 아니라 엉뚱한
결과로 형 변환이 되어서 나온다면? 그렇다... 이러한 점 때문에 프로그램이 꼴리는 데로 암시적으로 한 번 더
형 변환을 한다는 건 개발자 입장으로서는 알 수가 없기 때문에 지양해야 한다.
그리고 이 parseInt 란 놈은 아까도 테스트해서 봤지만 숫자와 문자가 섞인 문자열에서
문자열 앞 숫자까지 숫자로 형 변환을 해준다. 그런데 이것도 잠시 허탈하게 만드는 예가 있다.
var num_1 = '0x90555';
console.log(parseInt(num_1)); // 591189
이거는 어떤 값이 나올까?
테스트한 결과로다가 설명을 하자면 이건 분명 0 이란 숫자가 나와야 하지 않은가?
그런데 놀랍게도 이 결과물은 591189라는 숫자가 나온다.
어이없지 않은가? 그렇다 저 parseInt 메서드란 놈이 저걸 16진 수라 읽은 거다..
난 16진 수라는 의미로 적은 게 아닌데.... 그냥 0을 적고 그다음 문자열 x를 적은 의미로다가 작성한 건데 말이다.
이처럼 이 parseInt는 위 코드와 같이 생긴 첫 문자열 저렇게 생긴 넘은 16진수로 판단한다.
그래서 이 parseInt 메서드를 형 변환하고자 할 땐 두 번째 인자에 10이라는 숫자
즉, 10진 수라는 의미의 기수 10을 넣고 사용을 해야 한다.
var num_1 = '0x90555';
console.log(parseInt(num_1, 10)); // 0
이렇게 우리가 원하는 0이라는 값을 얻을 수 있다.
이 parseInt(문자열, 기수)의 메서드에 기수 넣는 매개변수 자리에는 2 보다 크고 36보다 작은 수를 넣어야 한다.
그렇지 않으면 NaN이라는 숫자를 반환한다.
내용을 다시 정리하는 차원에서 확인해보자.
var bool = false;
console.log(parseInt(bool, 16)); // ???
console.log(Number(bool)); // ???
Number() 메서드는 이 전 내용에서 얘기했듯이 false의 값은 Number() 형 변환하면 0 이란 값이
나온다는 것을 확인했으니 당연히 Number(bool) 은 0이 나오겠고,
parseInt 메서드는 첫 번째 매개변수가 문자열이 들어와야 하는데 문자열이 들어오지 않으면 프로그램이 알아서
ToString 규칙으로 인해 문자열로 바꾸고 그다음 형 변환을 시도한다고 했다.
그래서 bool 변수는 parseInt 가 ToString 규칙에 의해 'false' 문자열로 바꾸고
두 번째 매개변수를 16으로 지정해서 16 진수로 형 변환을 결정하고,
16진수의 숫자 범위는 0 ~ f 까지니깐, 문자열 'false'의 a 부분 문자열까지 해석하고
그래서 parseInt(bool, 16) 은 parseInt('0 xfa', 16)과 같다.
결과는 parseInt(bool, 16) 은 250이라는 결과 값이 나온다.
이렇게 parseInt 메서드를 이용한 명시적 형 변환을 알아봤다.
💻 Boolean 형 변환
이제 ToBoolean 규칙을 이용한 명시적 형 변환에 대해 알아보자.
var str_1 = '0';
var str_2 = '';
var arr = [1,2];
var obj = {a:1};
var numZero = 0;
var nullData = null;
var value;
console.log(Boolean(str_1)); // true
console.log(Boolean(str_2)); // false
console.log(Boolean(arr)); // true
console.log(Boolean(obj)); // true
console.log(Boolean(numZero)); // false
console.log(Boolean(nullData)); // false
console.log(Boolean(value)); // false
위 각 변수에 대해 Boolean 형 변환을 시도하면 console.log로 결과를 확인해 볼 수 있는데,
ECMAScript5 spec(사양)에서 ToBoolean의 규칙을 보면 왜 저렇게 결과가 나왔는지 쉽게 알 수 있다.
위 ToBoolean 링크를 걸어 놨으니 직접 들어가서 확인을 해도 되고, 참고용으로 아래 이미지를 첨부하겠다.
규칙을 하나씩 확인해 보자.
- undefined 를 Boolean 으로 형 변환 하면 false 된다.
- null 을 Boolean 으로 형 변환 하면 false 된다.
- number 는 +0, -0, NaN 은 Boolean 변환하면 false 그렇지 않으면 모두 true 가 된다.
- string 은 문자열 길이가 0 인 빈문자열을 Boolean 으로 형 변환 하면 false, 길이가 0 이상이라면 Boolean 형 변환시 true 가 된다.
위 예제 코드에서의 변수 value는 선언만 되었을 뿐 값이 초기화가 안되었기 때문에
undefined라서 Boolean을으로 형 변환을 하면 false 가 된다.
null 도 undefined와 마찬가지로 Boolean으로 형 변환 시 false로 형 변환을 하게 된다.
위 예제 코드에서의 변수 str_2 변수는 길이가 0 인 빈 문자열 값이니 Boolean 형 변환 시 false 가 된다.
그럼 str_1 변수는?
문자열의 길이(length)는 1 이므로 0 이상이기 때문에 문자열 '0' 이 들어가 있으므로
Boolean 형 변환시 true 가 된다.
위 예제 코드에서의 변수 numZero는 Boolean 형 변환 시 false가 된다.
Object는 Boolean 형 변환 시 무조건 true이다.
자바스크립트에선 배열도 객체라고 했다.
그래서 위 예제 코드의 변수 arr, obj는 Boolean 형 변환 시 무조건 true 가 된다.
'web 언어 > HTML5 & CSS & Javascript' 카테고리의 다른 글
JS - 자바스크립트(javascript) 동등 연산자 ==, === 이상하다, 혼란스럽다 - (1) (0) | 2022.04.25 |
---|---|
JS - 형 변환에 대하여 - (6) (0) | 2022.04.20 |
JS - 형 변환에 대하여 - (4) (0) | 2022.04.18 |
JS - 형 변환에 대하여 - (3) (0) | 2022.04.16 |
JS - 형 변환에 대하여 - (2) (0) | 2022.04.15 |