문자열
흔히 문자열은 단지 문자의 배열이라고 생각한다. 엔진이 내부적으로 배열을 쓰도록 구현되었는지는 모르겠지만 자바스크립트 문자열은 실제로 생김새만 비슷할뿐 문자 배열과 같지 않다는 사실을 알아야 한다.
var a = "foo";
var b = ["f", "O", "o"];
문자열은 배열과 겉모습이 닮았다. 이를테면 둘 다 length
프로퍼티, indexOf()
메소드, concat()
메서드를 가진다.
var a = "foo";
var b = ["f", "O", "o"];
a.length; // 3
b.length; // 3
a.indexOf("o"); // 1
b.indexOf("o"); // 1
var c = a.concat("bar"); // "foobar"
var d = b.concat(["b", "a", "r"]); // ["f", "o", "o", "b", "a", "r"]
a === c; //false
b === d; //false
a; // "foo"
b; // ["f", "o", "o"]
그렇다면 둘 다 '문자의 배열'이라고 할 수 있을까? 그렇지 않다.
a[1] = "O";
b[1] = "O";
a; // "foo"
b; // ["f", "O", "o"]
문자열은 불변 값(immutable)이지만 배열은 가변값(Mutable)이다. a[1]
처럼 문자열의 특정 문자를 접근하는 형태가 모든 자바스크립트 엔진에서 유효한 것은 아니다. 실제로 인터넷 익스플로러 구버전은 이를 문법 에러로 인식한다. a.charAt(1)
으로 접근해야 맞다.
문자열은 불면 값이므로 문자열 메서드는 그 내용을 바로 변경하지 않고 항상 새로운 문자열을 생성한 후 반환한다. 반면에 대부분의 배열 메서드는 그 자리에서 곧바로 원소를 수정한다.
c = a.toUpperCase();
a === c; // false
a; // "foo"
c; // "FOO"
b.push("!");
b; // ["f", "O", "o", "!]
그리고 문자열을 다룰 때 유용한 대부분의 배열 메서드는 사실상 문자열에 쓸 수 없지만, 문자열에 대해 불변 배열 메서드를 빌려 쓸 수는 있다.
a.join; // undefined
a.map; // undefined
var c = Array.prototype.join.call(a, "-");
var d = Array.prototype.map
.call(a, function (v) {
return v.toUpperCase() + ".";
})
.join("");
c; // f-o-o"
d; // "F.O.O"
다음은 문자열의 순서를 거꾸로 뒤집는 코드다. 배열에는 reverse()
라는 가변 메서드가 준비되어 있지만, 문자열은 그렇지 않다.
a.reverse(); // undefined;
b.reverse(); // ["!", "o", "O", "f"]
불행히도 문자열은 불변 값이라 바로 변경되지 않으므로 배열의 가변 메서드는 통하지 않고, 그래서 빌려쓰는 것 또한 안된다.
Array.prototype.reverse.call(a);
일단 문자열을 배열로 바꾸고 원하는 작업을 수행한 후 다시 문자열로 되돌리는 것이 또다른 꼼수다.
var c = a.split("").reverse().join("");
c; // "oof"
단순 문자열에 대해 좀 지저분하더라도 빠르게 써먹을 방법이 피룡하다면 이런 방법도 나쁘지 않다.
하지만 조심하자 복잡한 문자가 섞여 있는 경우 이방법은 통하지 않는다. 제대로 처리하려면 유니코드를 인식하는 정교한 라이브러리 유틸리티가 필요하다 마티아스 바이넨이 반든 에스레베르를 참고하자.
"문자열"자체에 어떤 작업을 빈번하게 수행하는 경우라면 관점을 달리하여 문자열을 문자 단위로 저장하는 배열로 취급하는 것이 더 나을 수 도 있다. "문자열 <-> 배열" 변환을 매번 번거롭게 신경쓰지 않아도 되니 시간과 노력을 아낄 수 있다. 문자열로 나타내야 할 때는 언제나 문자 배열에 join(")
매서드를 호출하면 된다.
참고
- You Don't Know JS ( 한빛 미디어 )
'JAVASCRIPT' 카테고리의 다른 글
[JS] this 란? (0) | 2022.01.26 |
---|---|
[JS][값][마무리] 값 vs 레퍼런스 (0) | 2022.01.26 |
[JS][값] 특수 값 (0) | 2022.01.26 |
[JS][값] 숫자 (0) | 2022.01.25 |
[JS][값] Array (0) | 2022.01.24 |
댓글