Ch3 네이티브
- 네이티브는 특정 환경(브라우저등의 클라이언트 프로그램)에 종속되지 않은 ECMAScript 명세의 내장 함수다.
- 가장 많이 쓰는 네이티브들은 다음과 같다.
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()
// new String을 예를 들자
var s = new String("Hello World")
typeof s // "object" 이며 "string"이 아니다.
- new String()은 내부 인자를 감싸는 문재열 래퍼를 생성하며 원시값 "Hello World"는 아니다.
- 위의 예를 보면 s는 String 클래스의 인스턴스고, 아래와 같이 나온다.
String {"Hello World"}
{
0: "H"
1: "e"
2: "l"
3: "l"
4: "o"
5: " "
6: "W"
7: "o"
8: "r"
9: "l"
10: "d"
length: 11
__proto__: String,
[[PrimitiveValue]]: "Hello World"
}
3.1 내부 [[Class]]
- 대부분 내부 [[Class]]는 해당 값과 관련된 내장 네이티브 생성자를 가리킨다 (단 null, undefined는 제외)
- Null() 이나 Undefined() 같은 네이티브 생성자는 없다.
- 그 밖의 원시값 (String, Number, Boolean)은 자동적으로 박싱되어 내부 [[Class]] 값이 String, Number, Boolean으로 표시되어 보인다.
3.2 래퍼 박싱하기
- 원시 값엔 프로퍼티나 메서드가 없으므로, .length나 toString()으로 접근하려면 원시 값을 객체 래퍼로 감싸줘야 한다.
- 자바스크립트는 원시 값을 알아서 박싱한다.
- 하지만 이런 이유때문에 원시값을 모두 네이티브 생성자로 생성할 필요가 없다. 브라우저는 이런 경우를 스스로 최적화하기 때문이다. 오히려 개발자가 나섰다가 더 느려진다.
- Boolean 값을 객체 래퍼로 박싱하여 사용하는 것은 객체가 truthy 값이기 때문에 문제가 발생한다. 사용하지 말자
- 수동으로 원시값을 객체 래퍼로 박싱하는 것을 Object 함수를 이용하자
3.3 언박싱
- 객체 래퍼의 원시값은 valueOf() 메서드로 추출한다.
- 암시적인 언박싱은 내용은 4장에서 확인하자
3.4 네이티브, 나는 생성자다
- 확실히 필요해서 쓰는 게 아니라면 생성자는 가급적 쓰지 않는 편이 좋다.
3.4.1 Array()
var a = new Array(1, 2, 3)
a // [1,2,3]
var b = [1, 2, 3]
b // [1,2,3]
-
결과적으로 같다.
-
Array 생성자는 인자로 숫자를 하나만 받으면 그 숫자를 해당 배열의 크기로 미리 정하는 기능이 있다.
-
실제로 슬롯에 값은 없지만 length로 보면 값이 있어보이는 배열이 완성된다.
var a = new Array(3)
a.length // 3
- 위 코드를 크롬에서 확인 결과 [empty x 3] 이런식으로 나온다. 물론 배열 안에 요소는 없다.
- 파폭에서 확인한 결과 [undefined, undefined, undefined] 라고 나온다. 물론 실제 값이 undefiend가 들어있는게 아니다.
- 책에선 장황하게 설명했지만 절대로 무슨 일이 있어도 이런 멍청한 방식으로 빈 슬롯 배열을 애써 만들어서 멋 부리지 말라고 하고 있다.
3.4.2 Object(), Function(), and RegExp()
- 이 세개의 생성자도 선택사항이다. (의도가 없다면 굳이 사용할 필요는 없다.)
- new Object() 같은 폼은 굳이 한 번에 하나씩 일일이 프로퍼티를 지정지 않는 이상 쓸 일이 없다.
- Function 생성자는 함수의 인자나 내용을 동적으로 정의해야 하는 드문 경우에 한해 유용하다고 하는데, 이런 경우라면 로직을 다시 생각해 보는것이 맞는 것 같다.
- 정규 표현식은 리터럴 형식이 쉽고 성능상의 이점이 있다고 한다. 하지만 RegExp()는 정규식 패턴을 동적으로 정의할 경우 의미가 있다고 한다.
const regexpPeopleName = name => {
return new RegExp(`${name}`, "ig")
}
const matches = someText.match(regexpPeopleName(name))
3.4.3 Date() and Error()
- 생성자 Date()와 Error()는 리터럴 형식이 없으므로 유용하다.
- date 객체값은 new Date()로 생성한다. 인자로는 날짜/시각을 받는다. (인자가 없으면 현재 날짜/시각으로 대체)
- date 유닉스 타임스탬프 값을 얻으려면 Date.now()를 쓰는게 쉽다.
- Error 생성자는 new가 있든 없든 결과는 같다.
- 현재의 실행 스택 콘텍스트를 포착하여 객체에 담는 것이다. 보통 throw 연산자와 함께 사용한다.
- 사람이 읽기 편한 메시지를 보려면 error 객체의 toString()을 호출하는 것이 좋다.
3.4.4 Symbol()
- ES6에서 처음 나온 원시 값 타입. 충돌 염려 없이 객체 프로퍼티로 사용 가능한, 특별한 '유일 값' 이다. (절대적 유일함은 아님)
- 주로 ES6의 특수한 내장 로직을 위해 고안 되었지만 심벌 정의는 얼마든지 가능하다
- 심벌을 직접 정의하려면 Symbol()을 사용한다. 앞에 new를 붙이면 안되는 유일한 생성자다.
3.4.5 네이티브 프로토타입
- 내장 네이티브 생성자는 각자의 .prototype 객체를 가진다.
- prototype 객체에는 해당 객체의 하위 타입별로 고유한 로직이 담겨 있다.
- 예를 들면 모든 String 객체는 String.prototype 객체에 정의된 메서드에 접근할 수 있다.
- 문자열 값을 변경하는 메서드는 없다. 수정이 일어나면 늘 기존값에서 새로운 값을 생성한다.
- 프로토타입 위임 덕분에 모든 문자열이 메서드를 공유한다.
- 네이티브 프로토타입 중 Function과 RegExp, Array는 조금 특이하다
- 네이티브 프로토타입을 변경할 수도 있지만 절대 하지 말자.
'JavaScript' 카테고리의 다른 글
[You don`t Know JS 정리] ch.5 문법 (0) | 2020.08.12 |
---|---|
[You don`t Know JS 정리] ch.4 강제변환 (0) | 2020.08.10 |
[React] react-pagination 구현 (0) | 2020.04.19 |
[React] Hooks의 종류 (0) | 2020.03.23 |
자바스크립트 Garbage Collector의 동작 (0) | 2020.03.07 |