본문 바로가기

Javascript

[JavaScript] 강제변환 - 명시적 강제변환, Explicit Coercion

반응형

 

이 글의 내용은 자바스크립트의 강제변환의 좋고 나쁨을 충분히 이해하고,

자신의 프로그램에 적절한지 스스로 현명하게 판단할 수 있도록 하기위한 내용을 작성했다.

 

어떤 값을 다른 타입의 값을 바꾸는 과정이 명시적이면 '타입 캐스팅, Type Casting' 이고,

값이 사용되는 규칙에 따라 암시적이면 '강제변환, Coercion' 이라고 한다.

'타입 캐스팅'은 정적 타입 언어에서 컴파일 시점에, '강제 변환'은 동적 타입 언어에서 런타임 시점에 발생한다.

 

본 글은 '강제 변환'을 세부적으로 나눠 '명시적 강제변한'과 '암시적 강제변환'으로 구별할 것이며,

'명시적 강제변환'은 코드만 봐도 의도적으로 탕입변환을 일으킨다는 사실이 명백한 반면,

'암시적 강제변환'은 다른 작업 도중 불분명한 부수 효과로부터 발생하는 타입변환을 뜻함을 참고바란다.

 

var a = 42;
var b = a + ""; // 암시적 강제변환
var c = String(a); // 명시적 강제변환

typeof a; // "number"
typeof b; // "string"
typeof c; // "string"

 

명시적 강제변환, Explicit Coercion


개발자들이 흔히 사용하는 타입 변환은 대개 이 명시적 강제변환 범주에 속한다.

코드가 명확하면 명확할수록 다른 개발자가 내 코드를 보더라도 쓸데없이 내 의도를 추론할 필요 없이 단번에 이해할 수 있다.

명시적 강제변환할 때는 앞에 new를 붙이지 않고 할당하면 된다.

 

문자열, String()  숫자, Number()

var a = 5959;
var b = String(a);
var c = a.toString();

b; // "5959"
c; // "5959"

var d = "5.9";
var e = Number(d);
var f = +d;
var g = 5+ +d;

e; // 5.9
f; // 5.9
g; // 10.9

 

비-문자열, String()  ► 숫자, Number()

/*
 * parseInt(문자열, 진법(default 10))은 잘 사용하면 의미있는 결과를 얻을 수 있으니 주의해서 사용하자.
 */

var a = "59";
var b = "59xyz";

Number(a); // 59
parseInt(a); // 59

Number(b); // NaN
parseInt(b); // 59

parseInt(1/0, 19); // 18
// (1) 첫번째 인수인 1/0의 결과는 Infinity라는 결과가 나오고 
// (2) 첫 번째 문자 "I"는 19진수에 18에 해당함
// (3) 두 번째 문자 "n"는 0-9, a-i의 범위 밖의 문자로 파싱이 중단됨

parseInt(0.000008); // 0 ("0.000008" ⇢ 0)
parseInt(0.0000008); // 8 ("8e-7" ⇢ 8)
parseInt(false, 16); // 250 ("false" ⇢ "fa")
parseInt(parseInt, 16); // 15 ("function..." ⇢ "f")
parseInt("0x10"); // 16
parseInt("103", 2); // 2

 

날짜, Date ► 숫자, Number

var a = new Date("Wed Sep 16 2020 00:00:00 GMT+0900");

+a; // 1600182000000

var b = new Date();

b; // Wed Sep 16 2020 00:00:00 GMT+0900 (대한민국 표준시)
+b; // 1600182000000

/*
 * 강제변환이 아닌 Date 객체로부터 일시를 얻는 방법 (권장)
 */
var timestamp1 = new Date().getTime();
var timestamp2 = Date.now();

timestamp1; // 1600182000000
timestamp2; // 1600182000000

 

* ► 불리언, Boolean

var a = "0";
var b = [];
var c = {};

var d = "";
var e = 0;
var f = null;
var g;

Boolean(a); // true
Boolean(b); // true
Boolean(c); // true
Boolean(d); // false
Boolean(e); // false
Boolean(f); // false
Boolean(g); // false

!!a; // true
!!b; // true
!!c; // true
!!d; // false
!!e; // false
!!f; // false
!!g; // false

/** 삼항 연산자 사용법 (비권장) */
var h = 59;
var i = h ? true : false; // 이때 h는 Boolean으로 강제 변환 후 포현식을 따짐

/** 삼항 연산자 사용법 (권장) */
var h = 59;
var i = Boolean(h) ? true : false;
var i = !!h ? true : false;

 


 Tip 

  ~(틸드) 은 강제변환 연산자이자, 가장 헷갈리는 연산자의 대명사다.

 

  자바스크립트 비트 연산자는 오직 32비트 연산만 가능하다고 했다.

  즉, 비트 연산을 하면 피연산자는 32비트 갑스로 강제로 맞춰지는데, ToInt32 추상 연산(ToNumber 강제변환)이 이 역할을 맡는다.

 

  ~ 연산자는 먼저 32비트 숫자로 '강제변환'한 후 NOT 연산(각 비트를 거꾸로 뒤집는 연산)을 하므로 ~x는 대략 -(x+1)와 같다.

    -(x+1) 은 ~의 의사 알고리즘(pseudo-algorithm)으로, 내부적으로 ~-1을 -0으로 만들지만,

    수학 연산이 아닌 비트 연산이므로 결과값은 0이 된다.

      예시 ) ~-1 // 0

 

/*
 * indexOf() : 문자열에서 특정 문자를 검색하고, 찾으면 검색된 인덱스 값(성공)을 못찾으면 -1(실패) 반환
 * 즉, 경계값인 -1을 기준으로 특정 문자가 해당 문자열에 포함하고 있는지 알 수 있음
 * ~을 함께 사용하면 indexOf()의 검색결과 실패시 falsy한 0으로, 성공시 truthy한 값으로 바꿈
 */
 
 
var a = "Hello World";

~a.indexOf("He"); // -1 (truthy value)
~a.indexOf("lo"); // -4 (truthy value)
~a.indexOf("ol"); // 0 (falsy value)
~a.indexOf("x"); // 0 (falsy value)

if (~a.indexOf("He") { // true
	// 찾음
} 
if (!~a.indexOf("x") { // true
	// 못 찾음
} 

 

  ~ 연산자는 숫자의 소수점 이상 부분을 잘라내기 위해 더블 틸드(~~)를 사용하기도 한다.

  더블 틸드(~~)는 처음 앞의 ~로 ToInt32 강제변환을 적용한 후 각 비트를 거꾸로 한다. 

  이후 두번째의 ~로 또 한번 뒤집는데, 결과적으로 원래 상태로 되돌린다. 이는 불리언의 패리티 이중 부정(||)과 유사하다.

  단, 이는 32비트 값에 한하여 안전하며, 음수에서는 Math.floor()과 결과값이 다르다는 사실을 조심하자 !

 

~~-49.6; // -49
Math.floor(-49.6); // -50

 


[강제변환 - 추상 연산, Abstract operation] chati.tistory.com/152

 

[JavaScript] 강제변환 - 추상 연산, Abstract operation

이 글의 내용은 자바스크립트의 강제변환의 좋고 나쁨을 충분히 이해하고, 자신의 프로그램에 적절한지 스스로 현명하게 판단할 수 있도록 하기위한 내용을 작성했다. 어떤 값을 다른 타입의 ��

chati.tistory.com

 

[강제변환 - 암시적 강제변환, Implicit Coercion] chati.tistory.com/154

 

[JavaScript] 강제변환 - 암시적 강제변환, Implicit Coercion

이 글의 내용은 자바스크립트의 강제변환의 좋고 나쁨을 충분히 이해하고, 자신의 프로그램에 적절한지 스스로 현명하게 판단할 수 있도록 하기위한 내용을 작성했다. 어떤 값을 다른 타입의 ��

chati.tistory.com

 


[참고] You Don't Know JS 타입과 문법, 스코프와 클로저 - 카일 심슨

 

반응형

❥ CHATI Github