[JavaScript]자바스크립트 강제변환 - 2

2021. 7. 14. 16:25Web_Programming/JavaScript

 

 

💻 암시적 변환

 

암시적 변환 : 숨겨진 형태로 일어나는 타입변환

 

암시적 변환이 코드를 더 복잡하고 이해하기 어렵게 많든다는 논란은아직까지도 많다고 합니다.

하지만, 교재에서는 긍정적인 관점으로 살펴보고있어 저 또한 장점을 위주로 살펴보겠습니다.

 

암시적 변환의 목적은 '불필요한 상세 구현을 줄이는 것'이라고 볼 수 있습니다.

 

 

👉 '암시적'이란?

 

예를 들어 타입변환의 의사코드를 살펴보면 아래와 같습니다.

Sometype x = SomeType(AnotherType(y))

즉, 타입이 바로 변환되는 것이 아닌 중간단계를 거치는 부분까지 표현이 되는데요,

 

이를 암시적으로 단순화 하여 표현 할 수있습니다.

Sometype x = SomeType(y)

이렇게 작성하여 코드 가독성을 높이고, 세세한 구현부를 추상화하는데에 도움이 될 수 있습니다.

 

이러한 부분이 암시적 변환의 장점이 될 수 있습니다.

 

👉 문자열 <-> 숫자

 

보통 많이 사용하는 암시적 문자열, 숫자 변환 방법은 +연산자입니다.

 

+연산자

숫자의 덧셈, 문자열 접합

 

이 둘의 구분은 보통 피연산자에 문자열이 있다면 문자열 접합으로 사용된다고 보는데,

var a = 42+"0";
a; // 420
var b = 42 + 0;
b; // 42

하지만 이것에는 예외가 존재하기 때문에 좀더 살펴보겠습니다.

var a =[1, 2];
var b = [3, 4];
a+b; //"1, 23, 4"

ToPrimitive 추상연산과정에서 valueOf() 를 수행하는데,

 

배열은 valueOf()반환이 어려워 ToString()으로 넘어갑니다.

 

따라서 문자열로 "1, 2" "3, 4" 이 반환되고, 이를 +연산하게 되면 문자열 접합으로 실행됩니다.

 

+ 객체의 경우는 객체 내에 valueOf()나 ToString()을 직접구현한 경우 다른 결과값이 나올 수 있습니다.

 

추가적으로 -, *, / 이 세 연산자는 숫자의 연산 기능이 전부이기때문에 매번 숫자로 강제변환이 됩니다.

 

 

👉 불리언 -> 숫자

 

많은 인자를 처리해야하는 경우, 명시적 강제변환 방식으로 사용하는데에는 한계가 있습니다.

 

이럴 때, 숫자(0/1)로 변환하여 사용하면 간편합니다.

for(int i=0;i<arguments.length;i++){
	if(arguments[i]){
    	sum+=arguments[i];
    }
}

sum += arguments[i] 👉 0 또는 1 로 변환

 

 

👉 * -> 불리언

 

암시적 강제변환 표현식

 

  • if문 조건표현식
  • for( ; ; )문 두번째 조건표현식
  • while() 조건표현식
  • ?: 삼항연산자 조건표현식
  • || 및 && 좌측 피연산자

 

👉 &&와 || 연산자

 

이 두연산자의 명칭은 논리연산자 이지만, 자바스크립트에서는 좀 다르게 사용됩니다.

 

해당 연산의 결과값이 두 피연산자중 한쪽의 값을 반환하기 때문입니다.

var a = 42;
var b = "abc";
a||b; //42
a&&b; //"abc"

|| 연산자 

결과가 true라면, 첫번째 피연산자값 반환

결과가 false라면, 두번째 피연산자값 반환

👉falsy값 사용의 경우, 무조건 뒤에 연산자 값으로 사용함을 주의

 

&& 연산자 

결과가 true라면, 두번째 피연산자값 반환

결과가 false라면, 첫번째 피연산자값 반환

👉truthy값 사용의 경우, 무조건 뒤에 연산자 값으로 사용함을 주의

 

 

이를 불리언으로 이용하게 되면 암시적 강제변환이 일어나 문제없이 사용가능합니다.

 

 

 

👉 Symbol의 강제변환

 

❗ Symbol()은 명시적 강제변환만 가능하고, 암시적 강제변환은 불가합니다.

 


 

💻 느슨한/엄격한 동등 비교

 

느슨한 동등비교는 ==연산자 : 동등함 비교시 강제변환을 허용

엄격한 동등비교는 ===연산자 : 동등함 비교시 강제변환을 허용❌

 

 

👉비교 성능

 

둘의 성능은 거의 차이가 없고 

사용에 있어 중요한 것은 강제변환 개입의 여부입니다.

 

"강제변환이 필요하다면 == , 필요없다면, ==="

 

 

👉 추상 동등 비교하기

 

== 연산자는 '추상적 동등 비교 알고리즘'으로 상술되어있으며,

 

비교시 두 값의 타입을 일치시켜 값만 보고 판단을 합니다.

 

+ 객체의 경우 두 객체의 레퍼런스가 동일 할 경우에만 동등 (강제변환 발생 ❌)

 

 

문자열 -> 숫자

var a = 42;
var b = "42";
a===b; //false
a==b; //true

===연산자는 강제변환이 허용되지 않으므로 false,

 

==연산자는 문자열 과 숫자의 경우,

 

문자열을 ToNumber()를 이용하여 강제변환한 후, 숫자 끼리 값을 비교

 

 

* -> 불리언

var a = "42";
var b = true;
a==b; //false

불리언 비교라고 해서 불리언으로 강제변환되어 비교되지않습니다.

불리언 비교 또한, ==연산자는

 

ToNumber()을 이용하여 강제변환 후, 숫자를 비교합니다.

 

❗ 따라서 == true 나 == false의 사용은 지양하는 것이 좋습니다.

 

 

null<->undefined

 

이 둘의 경우는 ==연산자에서 서로에게 타입을 맞춰 늘 true를 반환해줍니다.

 

 

객체 -> 비객체

 

객체의 경우는 ToPrimitive 강제변환으로 원시값을 추출한 후 비교합니다.

var a = "abc";
var b = Object(a);
a==b; //true
a===b; //false

 

❗ 하지만 null 과 undefined, NaN의 경우는 조심해야합니다.

var a = null;
var b = Object(a);
a==b; //false

var c = null;
var d = Object(c);
c==d; //false

var e = null;
var f = Object(e);
e==f; //false

null과 undefined는 객체 래퍼가 없어 Object()로 해석되어 일반객체가 되고,

 

NaN은 자신과도 늘 같지 않기 때문에 false를 나타냅니다.

 


 

💻 추상관계 비교

 

a<b 와 같은 비교 연산자를 '추상적 관계비교 알고리즘'이라고 합니다.

 

이는 모두 문자열일때와 그 외의 경우로 나뉩니다.

 

이또한, 먼저 ToPrimitive()로 강제변환이 일어나고 문자열이 모두 아닐경우는 ToNumber()로 변환하여 비교합니다.

 

모두 문자열일 경우는 단순 어휘 비교를 통해 결과를 냅니다. 

 

객체의 경우는 [object Object] 로 변환되어 비교가 불가하여 false가 반환됩니다.

 

추가적으로, 비교에서 >=와 같은 연산자는 < 연산 결과의 반댓값으로 반환하도록 되어있어 예외가 발생할 수 있습니다.

반응형