YOU DON'T KNOW JS 3장

박정훈·2022년 9월 18일
1

YOU DON'T KNOW JS

목록 보기
3/6
post-thumbnail

String(), Number(), Boolean(), Array(), Object(), Function(), RegExp(),
Date(), Error(), Symbol()... 네이티브는 사실 내장 함수다.

const a = new String("abc");
typeof a // 'Object'다! 'String'이 아니란 말이다!
console.log(a) // String {'abc'}

😱래퍼란 말이다.

new String("abc") 생성자의 결과는 원시 값 "abc"를 감싼 객체 래퍼다.

🤔내부[[Class]]

typeof가 'object'인 값에는 [[Class]]라는 내부 프로퍼티가 붙는다.

Object.prototype.toString.call([1,2,3]);
// '[object Array]'
Object.prototype.toString.call(/regex-literal/i);
// '[object RegExp]'
Object.prototype.toString.call(null);
// '[object Null]'
Object.prototype.toString.call(undefined);
// '[object Undefined]'
Object.prototype.toString.call("abc");
// '[object String]'
Object.prototype.toString.call(42);
// '[object Number]'
Object.prototype.toString.call(true);
// '[object Boolean]'

중간에 함정카드가 있다. Null() 이나 Undefined() 같은 네이티브 생성자는 없다! 그치만 뭐... 그렇다고 한다.
원시 값은 박싱을 거친 것을 확인 할 수 있다.

🙆‍♂️래퍼 박싱하기

자바스크립트는 원시 값을 알아서 박싱한다. 무슨말인가 하면

const a = "abc"
a.length // 3

개발자가 직접 객체 형태로 바꿔줄 필요? 없다. 엔진이 알아서 암시적으로 박싱하게 두는 것이 낫다. 브라우저가 스스로 최적화하게 냅두자.

🤥아니? 그래도 사용할래

그래도 사용하겠다면 주의하자.

const b = new Boolean(false);
if(!b) {
    console.log("이게 안되네...")
}

예?? 객체가 truthy라는 이유라서 라는데 자세한건 4장에서 나온다고 한다.👿

🎉언박싱

객체 래퍼의 원시 값은 valueOf() 메서드로 추출한다.

const c = new String('MALZA');
c.valueOf() // 'MALZA'

여기서도 암시적인 언박싱이 일어난다!

🔥계속해서 강조하지만 정말 명확한 이유가 없다면 의도적으로 생성자 폼을 사용하지 말자!🔥

😎네이티브, 나는 생성자다.

Object(), Function(), RegExp()

위 세 친구 생성자도 선택 사항이다.

분명한 의도가 있을때만 사용하도록 하자.

new Object() 같은 생성자 폼은 진짜, 거의 사용할 일이 없다. 리터럴 형태로 한 번에 여러 프로퍼티를 지정할 수도 있는데 굳이 한 번에 하나씩 일일이 프로퍼티를 지정하는 방법으로 돌아갈 필요가 있을까???

Function 생성자는 함수의 인자나 내용을 동적으로 정의해야 하는, 매우 드문 경우에 유용하다. 다만! eval()의 대용품이라고 착각하지 말자.

정규 표현식은 리터럴 형식으로 정의할 것을 적극 권장한다! 구문이 쉽고 무엇보다 성능상 이점이 있다.

자바스크립트 엔진이 실행 전 정규 표현식을 미리 컴파일한 후 캐시한다.

지금까지의 생성자들과는 달리, RegExp() 정규 표현식 패턴을 동적으로 정의할 경우에 의미 있는 유틸리티다.

const name = 'malza'
const namePattern = new RegExp("\\b(?:" + name + ")+\\b", "ig")
const matches = 'hello my name is malza'.match(namePattern)

📆Date()와 💥Error()

date 객체는 유닉스 타임스탬프 값(1970년 1월 1일부터 현재까지 흐른 시간을 초 단위로 환산)을 얻는 용도로 쓰인다.
ES5부터 Date.now()를 지원한다.

Error() 생성자는 new가 있든 없든 결과가 같다. 사람이 읽기 편하고자 한다면 그냥 error 객체의 toString()을 호출하자.

🧐Symbol()

ES6!! 새로운 원시 값 타입이다. 충돌 염려 없이 객체 프로퍼티로 사용 가능한, 특별한 유일 값이다! (절대적이지 않다.)

심벌은 프로퍼티명으로 사용 가능하나, 프로그램 코드나 개발자 콘솔 창에서 심벌의 실제 값을 보거나 접근하는건 불가능하다.

const malza = Symbol("my own Malza");
malza // Symbol(my own Malza)
malza.toString() // 'Symbol(my own Malza)'
typeof malza // 'symbol'

const home = {};
home[malza] = "ilsan"
Object.getOwnPropertySymbols(home)
[Symbol(my own Malza)]

심벌은 객체가 아니다. 단순한 스칼라 원시 값이다.
많은 개발자가 전용/특수/내부 프로퍼티라고 알리기 위해 사용한 언더스코어를 심벌로 완전히 대체할 가능성이 높다.

📚네이티브 프로토타입

내장 네이티브 생성자는 각각의 .prototype 객체를 가진다!
prototype 객체에는 해당 객체의 하위 타입별로 고유한 로직이 담겨 있다.

오오.. prototype이 등장했다. 아직은 낯선 친구지만 꼭 YOU DON'T KNOW JS 2권을 읽고 말겠다.

  • string.prototype.indexOf()
  • string.prototype.charAt()
  • string.prototype.substr(), substring(), slice()
  • string.prototype.upperCase()
  • string.prototype.trim()

프로토타입이 위임 덕분에 모든 문자열이 이 메서드들을 같이 쓸 수 있다.

책과 함께 본 포스팅
프로토타입

profile
그냥 개인적으로 공부한 글들에 불과

0개의 댓글