toString() 메소드란?
toString()은 어떤 대상을 문자열로 바꿔주는 메소드이다. Number 오브젝트에 있는 toString() 함수는 숫자를 문자열로 바꿔준다. String 오브젝트에 있는 toString()은 문자열을 문자열로 바꿔준다.
문자열을 굳이 문자열로 바꿔줄 필요는 없어 보인다.
왜 String 오브젝트에는 toString() 메소드가 존재하는 것일까?
그 이유를 알려면 먼저 프로퍼티(property)와 프로토타입(prototype)에 대해 알 필요가 있다.
프로퍼티와 프로토타입
프로퍼티는 name-value 쌍을 뜻한다.
예를 들면 {name: "Carrot", eyeColor: "blue", meow: meow()} 는 프로퍼티이다. 여기서 meow() 처럼 value 자리에는 문자열이나 숫자가 아니라 함수가 올 수도 있다.
프로토타입은 오브젝트의 프로퍼티를 담고 있는 상자 역할을 한다. 그래서 어떤 오브젝트의 인스턴스를 만들 때, 인스턴스가 원본 오브젝트의 프로퍼티를 사용하려면 오브젝트를 바로 참조하는 것이 아니라 prototype을 거쳐야 한다. 만약 String.prototype.toString()처럼 오브젝트의 프로퍼티를 바로 참조하는 경우가 아니라 인스턴트가 프로퍼티를 참조해야 하는 경우라면 자신 안에 있는 prototype으로 가는 링크인 __proto__를 타고 참조할 수 있다.
코드로 실습하기
new String()으로 built-in 오브젝트인 String 오브젝트의 인스턴스를 만든다. 이 인스턴스를 살펴보면 String 오브젝트가 가지고 있던 프로퍼티를 참조할 수 있는 prototype의 링크가 존재한다. 이것이 바로 __proto__이다. (아래 사진의 [[Prototype]] 가 바로 __proto__이다)
new String()으로 String 오브젝트의 인스턴스를 생성해주고 문자열 값으로는 "Hello!"를 준다. 그러면 자바스크립트 엔진은 프로퍼티(name-value 쌍)을 자동으로 생성해주는데 (0: "H"), (1: "e"), (length: 6)이 그 예이다.
(우리가 'e'를 얻으려고 value[1]을 하는 것은 인덱스 [1]로 'e'를 얻어온 게 아니라, name-value 쌍의 name인 '1'로 value를 불러온 것에 불과하다)
__proto__ (사진에서는 [[Prototype]] ) 옆에는 String이라고 쓰여 있다. 이것은 이 인스턴스가 String 오브젝트의 프로토타입을 참조할 수 있다는 것을 의미한다.
__proto__ 를 열어보자.
맨 아래로 내리다보면 toString()이 있고 __proto__가 또 있다.
옆에는 Object라고 쓰여 있다. 이것의 의미는 이 프로토타입(String 오브젝트의 prototype)은 Object의 prototype을 참조할 수 있다는 것을 의미한다.
__proto__ 안의 __proto__를 또 다시 펼쳐보자 ( __proto__.__proto__라고 표현할 수 있겠다)
toString()이 또 존재한다.
__proto__ 안에 toString()이 있고 __proto__.__proto__에 toString()이 또 존재하는 형식을 취하고 있다.
요약
상위의 __proto__는 String의 prototype 오브젝트를 참조할 수 있는 링크이고, 안에 또 존재하는 __proto__는 String의 조상님인 Object의 prototype을 참조할 수 있는 __proto__이다. 자바스크립트는 프로퍼티를 찾을 때 상위의 __proto__부터 참조하고, 없으면 그 안의 __proto__를 통해 찾는 방식으로 동작한다.
String의 toString() 메소드는 문자열을 문자열로 바꿔주는 기능을 하고,
Object의 toString() 메소드는 인스턴스의 타입을 문자열로 나타내는 기능을 한다.
▶ Object의 인스턴스 obj를 만들고 obj.toString()을 하면 [object Object]라는 괴상한 결과를 뱉어내는 것을 본 적이 있을 것이다. 여기서 object는 인스턴스라는 뜻이고 Object는 이 인스턴스의 타입이 built-in 오브젝트인 Object라는 뜻이다. 이것을 Number의 인스턴스에 똑같이 실행해보면 [object Number]라는 결과를 얻을 수 있다.
결론
String에 존재하는 toString()은 혹시라도 toString()을 호출했을 때 Object의 toString()이 호출되는 동작을 방지하고자 오버라이딩을 해 준 것이라고 생각하면 된다. 그래서 상위의 객체인 Object의 함수가 호출되지 않도록 자신의 대에서 끊을 수 있다. 이것이 바로 String 오브젝트에 얼핏 보기에 필요없어 보이는 toString()이 존재하는 이유이다.
'Front-end > Javascript' 카테고리의 다른 글
[JS] Javascript에서 Enum 사용하기 (0) | 2022.08.19 |
---|---|
[JS] 올림, 반올림, 내림 (ceil, round, floor) / 특정 자리수까지 0 채우기 (0) | 2022.08.08 |
[JS] onInput 이벤트 - 입력한 글자 실시간으로 화면에 출력하기 (0) | 2022.02.22 |
[JS] prototype 참고글 (0) | 2021.09.26 |
[JS] undefined와 null의 차이 (0) | 2021.09.23 |