TIL: Javascript의 원시 타입 파보기

Javascript에는 헷갈리는 개념들이 너무 많은 것 같다. 공부할 때마다 새로운 느낌이 든다… 오늘은 그 개념들 중 하나인 constructor에 대해서 오늘 알게된 것을 정리해보려한다. 이를 통해 내 머릿속의 개념들이 차곡차곡 정리되었으면 좋겠다.

접근

이번 자바스크립트 스터디에서 Symbol을 주제로 범위를 정해서, Symbol에 대해서 공부를 하고 있었다. 그 전 스터디에서는 함수를 주제로 했었는데, 거기서 내가 발표한 것은 Ordinary Object에 관한 내용이었다. Ordinary Object가 생성될 때 기본적으로 가지게 되는 Internal Methods와, Function Object의 경우 추가적으로 갖고 있는 Internal Methods에 대해서 공부했었다.

자세한 글은 다시 공부하는 Object 이 글을 참조..

그런데 여기서 중요한 것은 constructor를 가지고 있는 아이들은 모두 함수인데, Symbol()을 이용하여 새로운 Symbol을 만들 때, 이 값은 constructor를 갖는다는 것이다..

Screen Shot 2020-02-09 at 2 29 50 PM

Symbol로 만든 아이는 객체가 아니라 원시적인 값이다. 그런데 함수만 가질 수 있는 constructor를 왜 갖고 있는가??

원시타입은 ‘원래’ 객체이다??

우선, 제일 먼저 헷갈릴 수 있는 것부터 짚고가면, 원시 타입은 프로퍼티나 메소드를 가질 수 없다. 하지만, 원시 타입으로 프로퍼티나 메소드를 호출하게 될 경우, 원시 타입과 연관된 객체(원시 타입 생성자인 객체)로 일시적으로 변환되어 __proto__를 공유하게 된다. 그렇게 원시타입에도 constructor를 순간적으로 볼 수 있다.

그러면 다시, 자바스크립트의 원시타입을 제외한 아이들은 모두 객체이다. 그리고 자바스크립트는 모두 Object.prototype으로 묶여있다. 이 말의 뜻은 결국 원시타입을 생성할 때에도, 특정 빌트인 객체를 통해 생성하게 된다.

그렇다면 왜 원시타입은 객체가 아니라 원시타입이며, 원시타입은 왜 생성자를 통해서 생성되지만 객체가 아닌가??? 원시타입과 객체의 내부적인 차이를 봐야할 것 같다.

Screen Shot 2020-02-09 at 2 52 29 PM

여기서 Boolean ConstructorBoolean을 생성할 때, 생성하는 객체의 기본 attributes가 아래와 같이 구성되어 있다.

// %Boolean.prototype% (Boolean.prototype) -> new Boolean()해서 새로운 원시타입을 생성할 때
{
    [[Writable]]: false,
    [[Enumerable]]: false, 
    [[Configurable]]: false
}

내가 제대로 이해한 것이 맞다면, 원시타입은 이런 객체 attributes 구성으로 인해 값만 조회할 수 있는 것이 아닐까 생각한다.

그리고 그 값만 조회할 수 있는 Internal slot[[BooleanData]]를 통해서 원시타입의 값을 접근할 수 있도록 하는 것이다.

더 자세히 들어가면, Boolean.constructor[[Prototype]]Internal slot으로 Function.prototype을 값으로 가지고 있다. 즉, Boolean 생성자를 생성한 함수는 Function.prototype이라는 의미일 것이다. 그리고 Boolean.prototype의 값으로는 %Boolean.prototype%이라는 고유 객체를 가지고 있고, 이 프로퍼티가 위 코드의 attributes 구성을 가지고 있어, 인스턴스(원시타입)를 생성할 때 해당 구성으로 생성되어 원시타입으로 이루어지게 되는 것이다. 특정 생성자를 통해 생성한 인스턴스의 __proto__생성함수.prototype이라는 것은 다들 알고 있을 것이다..(내가 헷갈려서 적움 ㅠㅠ)

결론

프로토타입을 다시 복습하고, 원시 타입에 관한 설명이 들어있는 명세서를 읽어본 결과, 원시 타입은 원시 타입을 생성하는 객체들로 인해 생성되는 원래는 객체이지만, 특정 내부 원시타입을 생성하는 객체들의 내부적으로 가지고 있는 attributes의 구성차이로 인해 객체에서 값으로 설정되어 원시타입으로 내려보내지는 것 같다.

내가 읽은 내용의 번역이 잘못되었을 수도 있어 100% 확신을 못하는 것은 슬프지만, 나름대로 이정도 결론을 내린 것만으로 만족할 수 밖에 없을듯…하다……..

이 글을 읽으신 분들 중에 제가 적은 어떤 글이 잘못된 것 같으면 가차없이 얘기해주시면 감사하겠습니다ㅠㅠ 자스고수님들… 진실을 알고싶어용..

참고