[자바스크립트/Javascript] 강제변환(2)

cool_kim·2021년 7월 14일
0

Javascript

목록 보기
4/7
post-thumbnail

4.4 암시적 변환

: 부수 효과가 명확하지 않게 숨겨진 형태로 일어나는 타입변환
📍 불필요한 상세 구현 줄이는게 목표

암시적?

임의의 타입 → Sometype 타입 변환

  • 엄격한 타입 언어의 강제 변환 : 원래 타입 → Another 타입 → Sometype타입
  • 암시적 타입 언어의 강제 변환 : 원래 타입 → Sometype타입
    • 지저분한 코드를 감출 수 있음

⚠️ 명시적 강제변환이 물론 좋지만 무조건적으로 암시적 강제변환이 나쁜건 아니다.

문자열 ↔️ 숫자

🔹 + 연산자 : 숫자의 덧셈 or 문자열 접합으로 오버로드 → 어떻게 두개의 연산을 구분?

    • 알고리즘은 한쪽 피연산자가 문자열이거나 문자열 표현형으로 나타낼 수 있으면 문자열 붙이기 수행
    • ToPrimitive 추상 연산을 수행
    • ToPrimitive 는 number 콘텍스트 힌트를 넘겨 [[DefaultValue]] 알고리즘 호출
      ⇒ ToNumber 추상 연산이 객체를 다루는 방법과 일치❗
  1. a + "" : 숫자를 문자열로 강제 변환하는 관용코드 (암시적 강제변환임)
    ⚠️ 평범한 원시 숫자 값이 아닌 개체라면 문자열이 달라질 수 있음

🔹 - 연산자 : 숫자 뺄셈 기능이 전부

  1. a - 0 : a 값을 숫자로 강제변환
    곱하기, 나누기 연산도 마찬가지
  2. 객체 값에 - 연산 : + 연산과 비슷
    - 배열은 모두 문자열로 강제변환 뒤 숫자로 강제변환 그후, - 연산

불리언 ➡️ 숫자

👍 복잡한 형태의 불리언 로직을 숫자 덧셈 형태로 단순화 할 때 편리함

🔹 !!arguments[i] : true/false로 강제 변환

  • true / truthy : 1
  • false / falsy : 0

* ➡️ 불리언

🔹 if () 문의 조건 표현식
🔹 for ( ; ; ) 에서 두 번째 조건 표현식
🔹 while ()do ... while() 루프의 조건 표현식
🔹 ? : 상항 연산 시 첫 번째 조건 표현식
🔹 ||&& 의 좌측 피연산자

📍 콘텍스트에서 불리언이 아닌 값이 사용되면 일단 불리언 값으로 암시적 강제변환 됨.


&&|| 연산자

💡 자바스크립트에서 두 연산자는 다른 언어와 달리 실제로 결괏값이 논리 값이 아님!!
&& 또는 || 연산자의 결괏값이 반드시 불리언 타입이어야 하는 것은 아니며 항상 두 피연산자 표현식 중 어느 한쪽 값으로 귀결

a || b;
a ? a : b; //위와 같은 코드

a && b;
a ? b : a; //위와 같은 코드

⚠️ " " 값은 falsy값임

🔹 || 연산자

  • falsy값은 무조건 건너 뛸 경우에만 사용해야함
  • 아닐 경우 조건 평가식을 삼항 연산자로 더 명시적으로 지정해야함

🔹 && 연산자

  • 가드 연산자 : 첫번째 피연산자의 평가 결과가 truthy일 때에만 두번째 피연산자 선택

📍 복합 논리 표현식의 작동 방식

  • 복합 표현식 평가 → 불리언으로 암시적 강제 변환

심벌 강제변환

: 심벌 -> 문자열 명시정 강제변환은 👌, 암시적 강제변환은 ❌

🖐️ BUT! 불리언 값으로는 명시적/암시적 모두 강제변환 가능





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

🔹 느슨한 동등 비교 : == ➡️ 강제변환 ⭕

🔹 엄격한 동등 비교 : === ➡️ 강제변환 ❌

📌 강제 변환이 필요하다면 == 필요하지 않다면 === 사용

추상 동등 비교

: == 연산자 로직은 추상적 동등 비교 알고리즘

  • 비교할 두 값이 같은 타입이면 값을 보고 식별
  • NaN은 그 자신과도 동등하지 않음
  • +0과 -0은 동등하지 않음

📍 객체의 느슨한 동등 비의 경우 정확히 똑같은 값에 대한 레퍼런스일 경우에만 동등 ➡️ 강제변환 일어나지 않음!

문자열 ➡️ 숫자

var a = 42;
var b = "42";

a === b; // false
a == b; // true

🔹 ===는 강제 변환이 안되므로 false
🔹 == 는 피연산자의 타입이 다르면 비교알고리즘에 의해 피연산자 값이 암시적으로 강제변환되어 true


* ➡️ 불리언

var x = true;
var y = "42";

x == y; //false
  1. Type( x ) 는 불리언이므로 ToNumber(x) → 1 로 강제변환
  2. 1 == "42"가 되는데 타입이 다르므로 알고리즘 수행
  3. "42"는 42로 바뀌어 1 == 42 → false가 됨

📍 == true or == false 와 같은 코드는 안쓰는 것이 좋음
=== 는 괜찮아요!


null ➡️ undefined

🔹 null과 undefined를 느슨한 동등 비교하면 강제변환
🔹 이 강제변환은 안전하고 예측 가능하며, 어떤 다른 값도 비교 결과 긍정 오류를 할 가능성이 없음


객체 ➡️ 비객체

var a = "abc";
var b = Object( a );

a === b; //false
a == b; //true

var x = null;
var y = Object( x );
x == y; // false

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

var e = NaN;
var f = Object( e );
e == f; //false
  • b는 ToPrimitive연산으로 "abc"라는 단순 스칼라 원시값으로 강제변환되어 a == b가 true 맞음
  • a == b 는 true가 맞음
  • null과 undefined는 객체 래퍼가 따로 없어 박싱할 수 없음
  • NaN은 해당 객체 래퍼인 Number로 박싱되지만 결국 조건식은 NaN == NaN이 되어 false가 됨


희귀 사례

falsy비교

"0" == false; //true
false == 0; //true
false == ""; //true
false == []; //true
"" == 0; //true
"" == []; //true
0 == []; //true

➡️ 긍정 오류


다양한 오류

[] == ![] //true

2 == [2]; //true
"" == [null]; //true

0 == "\n"; //true



4.6 추상 관계 비교

: a < b 비교 과정

🔹 피연산자 모두 문자열일 때

  • 각 문자를 단순 어휘로 비교(알파벳 순서로)

🔹 그 외의 경우

  • 어느 한쪽이라도 문자열이 아닐 경우 양 쪽 모두 ToNumber로 강제변환하여 비교

📍 자바스크립트 엔진은 <= 를 '더 크지 않은'(!(a > b) → !(b < a))의 의미로 해석

profile
FE developer

0개의 댓글