일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Next.js
- 구현
- REACT
- 회고
- 코딩일기
- 토이 프로젝트
- three.js
- 기본 문법
- 브루트포스
- js
- poiemaweb
- 엔트리포인트
- HTML5
- 자료 구조
- 세그먼트 트리
- styled-components
- 프론트엔드
- 시뮬레이션
- 해시를 사용한 집합과 맵
- 백준
- 개발 회고
- 자바
- 티스토리챌린지
- State
- 오블완
- 수학
- 자바스크립트
- 모던 자바스크립트 튜토리얼
- react-three/fiber
- JavaScript
- Today
- Total
코딩하는 고릴라
[JS] 문자열을 정렬시킬 수 있을까? 본문
let arr = ['r', 'a', 'n', 'd'];
arr.sort((a, b) => a.localeCompare(b));
console.log(arr); // [ 'a', 'd', 'n', 'r' ]
아시다시피 배열의 경우에는 sort 메서드를 통하여 간편하게 배열 내 값들을 정렬시킬 수 있습니다.
그렇다면, 문자열도 위와 같은 방식으로 정렬시킬 수 있을까요?
let str = 'andomword';
[].sort.call(str, (a, b) => a.localeCompare(b));
console.log(str); // ???
문자열 자체에는 sort 메서드를 호출할 수 없어, call을 활용해 배열의 메서드인 sort를 빌려와 사용하였습니다.
문자열은 이터러블이며 유사 배열 객체이기 때문에 배열의 sort 메서드를 빌려와 사용해도 크게 문제가 없을 것이라 생각했습니다.
🦍 이터러블
- 프로퍼티로 [Symbol.iterator] 숨김 프로퍼티를 가진다.
- 이를 활용해 for ... of 와 같은 반복문으로 값을 순회할 수 있다.
🦍 유사 배열 객체
- 객체 내 값을 인덱스로 접근할 수 있다.
[].sort.call(str, (a, b) => a.localeCompare(b));
^
TypeError: Cannot assign to read only property '0' of object '[object String]'
하지만, 예상과는 다르게 위와 같은 에러를 결과로 확인할 수 있었습니다.
읽기 전용인 프로퍼티에 새로운 값을 할당할 수 없다는 에러인데, 자바스크립트에서의 문자열은 이터러블, 유사 배열 객체라는 특성 이외에도 원시형 값이 가진 특징인 불변성을 가집니다.
let word1 = 'abcd';
word1 = 'efgh';
위 코드에서 word1은 문자열 'abcd'가 저장된 메모리를 참조합니다. 그리고 아래에서 해당 변수의 값을 수정하면 메모리에 올라가 있던 기존 문자열이 수정되는 것이 아닌 새로운 메모리 공간에 'efgh'를 등록 후 해당 메모리를 참조하도록 변경하는 것입니다. 따라서 메모리에 올라가있던 'abcd' 문자열 값이 변경되지 않습니다.
그렇다면 위에서 배열의 sort 메서드를 빌려와 문자열에 사용하려고 했을 때, 새로운 값을 읽기 전용 프로퍼티인 '0' 에 할당할 수 없다는 에러를 보고 왜 이런 결과가 나왔는지 예측해 볼 수 있습니다.
sort 메서드의 동작 방식을 살펴본 적은 없으나, 내부적으로 각 인덱스에서의 값을 변경해 주는 로직이 포함되어 있을 것이라 생각해 볼 수 있었습니다. 정말로 이런 방식으로 동작되는지 직접 살펴보도록 하겠습니다.
ECMAScript® 2025 Language Specification
Introduction This Ecma Standard defines the ECMAScript 2025 Language. It is the sixteenth edition of the ECMAScript Language Specification. Since publication of the first edition in 1997, ECMAScript has grown to be one of the world's most widely used gener
tc39.es
comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
If
obj be ? ToObject(this value).
Let,,,,
j < itemCount,
Repeat, whileSet(obj, ! ToString(𝔽(j)), sortedList[j], true).
Perform ?j to j + 1.
Set....
obj.
ReturnECMA-262 명세에서 배열의 sort 메서드에 대한 내용을 살펴보면, obj에 정렬 대상이 될 객체를 할당하고, obj의 인덱스에 새로운 값을 할당하며, 최종적으로 정렬된 형태의 obj를 반환하는 것을 볼 수 있습니다.
위 내용에 비추어 보았을 때, Array.prototype.sort() 메서드는 배열 대상이 되는 객체를 복사하여 사용하지 않고, 해당 객체의 값을 직접 조작하여 정렬시킨다는 것을 알 수 있었습니다. 이 때문에 read only 프로퍼티를 가진 문자열에서는 sort 메서드를 사용할 수 없었던 것입니다.
그래서 저 같은 경우에는 일반적으로 다음과 같은 방식을 통해 문자열을 정렬시킵니다.
let str = 'randomword';
str = [...str].sort((a, b) => a.localeCompare(b)).join('');
console.log(str); // addmnoorrw
문자열을 배열로 변형 후, 배열에서 정렬시킨 다음 다시 문자열로 변환시키는 과정
'Javascript' 카테고리의 다른 글
모던 자바스크립트 튜토리얼 - 2. 객체: 기본 (0) | 2024.11.12 |
---|---|
모던 자바스크립트 튜토리얼 - 1. 자바스크립트 기본 (0) | 2024.11.11 |
[Javascript] 코드로 보는 비동기 작업 이해하기 (0) | 2024.06.19 |
[Javascript] 데이터 타입과 변수 (0) | 2023.12.01 |
[Javascript] 기본 문법 (0) | 2023.11.30 |