JS가 그대를 속일지라도

서지·2021년 9월 30일
20

Photo by Bruce Warrington on Unsplash

해당 글은 Gapur Kassym님의 Here Are 7 Weird Things in JavaScript를 번역한 글입니다.

개요

자바스크립트는 아름답고도 이상한 언어입니다
이 글에서는 자바스크립트에서 특별히 이상한 7가지에 대해 예제 코드와 함께 알아보겠습니다

[]![]은 같다.

[] == ![]; // -> true
+[] == +![]; // -> true

동등 연산자가 좌우 피연산자를 각각 숫자로 변환 한 후 비교합니다
[]![] 는 각각 다른 과정을 거쳐 0으로 변환됩니다

[] == ![]; // -> 0 == 0 -> true

true![]와 같지 않다, 그런데 이제 []와도 같지 않다

배열은 true와 같지 않습니다, 하지만 배열의 부정도 true와 같지 않습니다
그런데 배열은 false와 같고 배열의 부정 역시 false와 같습니다

true == []; // -> false
true == ![]; // -> false

false == []; // -> true
false ==  ![]; // -> true

좌우 피연산자를 숫자로 변환하는 과정에서 []0으로 변환되고, true0으로 변환됩니다.

true == ![]; // -> false
Number(true); // -> 1
Number([]); // -> 0
1 == 0; // -> false

truefalse이다

!!"false" == !!"true" // -> true
!!"false" === !!"true" // -> true

truetruthy 하며 1로 변환됩니다.
'true'는 문자열이기에 NaN으로 변환됩니다.
NaN은 어떤 값과 비교해도 같지 않으며, 다른 NaN과 비교해도 같지 않습니다.

true == "true"; // 1 == NaN -> false
false == "false"; // 0 == NaN -> false

false는 비어있지 않은 문자열이기에 truthy 합니다.

!!"false"; // -> true
!!"true"; // -> true

null 과 0 비교

null > 0; // -> false
null >= 0; // -> true

null == 0; // -> false

동등 연산자는 null0으로 변환합니다. 그렇기에 null >= 0null > 0false가 됩니다.
하지만 null == 0은 왜 false일까요? 00은 같아야 하지 않을까요?

nullNaN과 같이 비교시에 특별한 규칙이 있습니다.
nullnull, undefined를 제외한 모든 값과 같지 않습니다.

3개의 수 비교

1 < 2 < 3; // -> true
3 > 2 > 1; // -> false

해당 코드는 아래의 과정으로 동작합니다

1 < 2 < 3; // 1 < 2 -> true
true < 3; // true -> 1
1 < 3; // -> true

3 > 2 > 1; // 3 > 2 -> true
true > 1; // true -> 1
1 > 1; // -> false

0.1 + 0.2의 결과

0.1 + 0.2 == 0.3 // -> false
0.1 + 0.2 // -> 0.30000000000000004

이 문제에 대한 해답은 해당 글에서 확인할 수 있습니다.

'64 비트 IEEE 754 형식'은 숫자를 표현할 때 사용하는 정해진 비트 수가 있다(부호 1, 지수부 11, 가수부 52). 그래서 0.1(=1/10), 0.2(=1/5) 같이 2진법으로 나타낼 때 소수점 아래가 무한히 이어지는 숫자들을 '64 비트 IEEE 754 형식'으로 나타내려면, 비트 안에 수가 담길 수 있도록 가수(mantissa)부의 정해진 자리에서 수를 반올림해야 한다.
자바스크립트에서 0.3(=3/10)을 입력한다면 수는 한 번 반올림된다. 하지만 0.1 + 0.2를 연산하면 0.1과 0.2에서, 그리고 0.1과 0.2를 더한 값에서 반올림되기 때문에 0.1 + 0.2와 0.3은 다른 값이다.

Array.prototype.sort()의 기본 동작

[10, 1, 3].sort() // -> [1, 10, 3]

Array.prototype.sort()의 기본 동작에서는 각 값을 문자열로 변환합니다.
그런 다음 UTF-16 코드 유닛의 시퀀스를 비교합니다.

javascript에서 숫자를 정렬할 때에는 아래의 방식으로 구현해야합니다.

[10, 1, 3].sort((a, b) => a - b) // -> [1, 3, 10]

끝맺으며

긴 긁 읽어주셔서 감사하며, 유용한 글이 되었으면 좋겠습니다.
다들 즐겁게 코딩하시고 JS가 그대를 속일지라도, 그냥 그런갑다 해주세요
감사합니다.

참고

profile
아무튼 행복한 사람

4개의 댓글

comment-user-thumbnail
2021년 9월 30일

Null과 0 비교에서
하지만 null == 0은 왜 true일까요?가 아니라 하지만 null == 0은 왜 false일까요? 인것 같아요!

좋은 글 잘 읽었습니다 👍

1개의 답글
comment-user-thumbnail
2021년 10월 1일

재밌게 봤습니다. JS가 괴랄하긴 하죠. ㅠㅠ

1개의 답글