본문 바로가기
FE/javascript

[JS] Array.prototype.sort()의 허점

by 빠니몽 2024. 6. 20.

06.20.2024

1. JavaScript Sort Method의 이상한 점

JS를 쓰면서 sort를 사용해야 할 일이 있을 때 사실 빌트인 정렬 함수를 많이 쓰곤 했다.

굳이 정렬 메소드를 재생성해야할 필요가 없었기 때문이다. 

그런데 유데미 강의를 들으며 이상한 점을 알게되었다.

["B", "C", "A"].sort();
// ["A", B", "C"]
[6, 4, 15, 10].sort();
// [10, 15, 4, 6]

 

자바스크립트에서는 이 코드가 동작하지 않는다는 것이다.

분명 sort 메소드를 쓸 때 실행 오류를 한 번도 마주한 적이 없는데 이런 기본적인 함수에서 숫자가 정렬되지 않는다는게 믿겨지지가 않았다.

2. Why?

왜 자바스크립트의 정렬 함수는 숫자를 정렬하지 못하는 것일까?

그 답은 공식 문서에서 찾아볼 수 있다.

자바스크립트 배열 정렬 메소드 공식 문서

MDN 공식문서에 따르면 배열의 정렬 메소드는 인자들을 문자열로 바꾼 뒤 UTF-16 코드를 오름차순 정렬을 한다고 한다.

위에서의 예시를 다시 보면 왜 10번 대의 숫자들이 앞으로 정렬되었는지 이해할 수 있다.

3. 대체 방법

그렇다면 숫자의 배열을 정렬하고 싶을 때는 무조건 함수를 새로 짜야 하는 건가요?

다행히도 sort 함수는 인자로 함수를 받을 수 있다.

function compareNumbers(a, b) {
  return a - b;
}
[1, 4, '3', 50, '40'].sort(compareNumbers); // [1, '3', 4, '40', 50]

 

이렇게 sort 함수에 인자로 함수를 넣을 시 리턴값에 따라 인자를 정렬하며 문자열과 정수형, 실수형의 계산도 무리없이 해낸다.

규칙은 다음과 같다.

  • 양수를 리턴할 경우, b - a 순으로 정렬
  • 음수를 리턴할 경우, a - b 순으로 정렬
  • 0을 리턴할 경우, 인자의 변경 없음

함수를 선언하지 않고 람다 함수로 대체할 수도 있다.