네이티브 프로로타입
내장 네이티브 생성자는 각자의 .prototype
객체를 가진다.
prototype
객체에는 해당 객체의 하위 타입별로 고유한 로직이 담겨있다.
이를테면 문자열 원시 값을 확장한 것까지 포함하여 모든 String
객체는 기본적으로 String.prototype
객체에 정의된 메서드에 접근할 수 있다.
문서화 관례에 따라 String.prototype.XYZ는 String#XYZ로 줄여쓴다. 다른 .prototype도 마찬가지이다.
String#indexOf()
: 문자열에서 특정 문자의 위치 검색String#charAt()
: 문자열에서 특정 위치의 문자를 반환String#substr()
,String#substring()
andString#slice()
: 문자열 일부를 새로운 문자열로 추출String#toUpperCase()
andString#toLowerCase()
: 대문자/소문자로 변환된 새로운 문자열 생성String#trim()
: 앞/뒤 공란이 제거된 새로운 문자열 생성
이 중 문자열 값을 변경하는 메서드는 없다. 수정이 일어나면 늘 기존 값으로부터 새로운 값을 생성한다.
프로토타입 위임 덕분에 모든 문자열이 이 메서드를 같이 쓸 수 있다.
var a = " abc ";
a.indexOf("c"); // 3
a.toUpperCase(); // " ABC "
a.trim(); // "abc"
각 생성자 프로토타입마다 자신의 타입에 적합한 기능이 구현되어 있다. 가령 Number#toFixed()
는 고정 소수점 이하 자릿수까지 끊긴 숫자를 문자열로 바꾸어 반환하고 Array#concat()
는 배열을 병합한다. 모든 함수는 Function.prototype
에 정의된 apply()
, call()
, bind()
메서드를 사용할 수 있다.
그러나 모든 네이티브 프로토타입이 모두 그렇게 평범한 것은 아니다.
typeof Function.prototype; // "Function"
Function.prototype(); // 빈 함수!
RegExp.prototype.toString(); // "/(?:)/"
"abc".match(RegExp.prototype); // [""]
이렇게 네이티브 프로토타입을 변경할 수도 있지만 이는 결코 바람직하지 않은 발상이다.
프로토타입은 디폴트다.
변수에 적절한 타입의 값이 할당되지 않은 상태에서 Function.prototype
-> 빈 함수, RegExp.prototype
-> '빈' 정규식, Array.prototype
-> 빈 배열은, 모두 '디폴트' 값이다.
ES6 부터는
vals = vals || 디폴트 값
식의 구문 트릭은 더이상 필요없다. 왜냐하면 함수 선언부에서 네이티브 구문을 통해 인자의 디폴트 값을 설정할 수 있기 때문이다.
프로토타입으로 디폴트 값을 세티앟면 사소하지만 추가적인 이점이 있다. .prototype
들은 이미 생성되어 내장된 상태이므로 단 한번만 생성된다. 그러나 []
, fucntion(){}
, /(?:)/
를 티폴트 값으로 사용하면 isThisCool()
를 호출할 때마다 디폴트 값을 다시 생성하므로 그만큼 메모리/CPU가 낭비된다.
그리고 이후에 변경될 디폴트 값으로 Array.prototype
를 사용하는 일은 없도록 유의하자.
정리하기
자바스크립트는 원시 값을 감싸는 객체 래퍼, 즉 네이티브를 제공한다. 객체 래퍼에는 타입별로 쓸만한 긴으이 구현되어 있어 편리하게 사용할 수 있다.
"abc"같은 단순 스칼라 원시 값이 있을 때, 이 값의 length
프로퍼티나 String.prototype
에 정의된 메서드를 호출하면 자바스크립트는 자동으로 원시 값을 박싱하여 필요한 프로퍼티와 메서드를 쓸 수 있게 도와준다.
참고
- You Don't Know JS ( 한빛 미디어 )
'JAVASCRIPT' 카테고리의 다른 글
[JS][강제변환] 추상연산 ToNumber (0) | 2022.02.09 |
---|---|
[JS][강제변환] 추상 연산 ToString (0) | 2022.02.08 |
[JS][네이티브] Symbol() (0) | 2022.02.08 |
[JS][네이티브] Date() and Error() (0) | 2022.02.08 |
[JS] 프로토타입(prototype) (0) | 2022.02.03 |
댓글