YOU DON'T KNOW JS - 2
#
2023-02-24#
Chapter3 네이티브#
Chapter4 강제변환#
개요책에서 네이티브에 대한 내용을 읽다가 프로토타입 내용이 있어서 조금 깊게 살펴보는 시간을 가졌다.
#
네이티브네이티브란 특정 환경에 종속되지 않은 ECMAScript 명세의 내장 객체를 뜻한다.
가장 많이 사용하는 네이티브는 아래 목록정도가 있다.
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()
tip
리터럴 표현식을 사용하지 않고 직접 네이티브 생성자를 사용하면 객체 래퍼로 표현되니 특별한 상황이 아니라면 리터럴 표기법을 사용하는것을 권장한다.
사실 원시값에는 프로퍼티나 메서드가 없어서 length
, toString()
같은 메서드를 사용하려면 객체 래퍼로 감싸주어야 하는것이 맞다.
하지만, 자바스크립트 엔진이 호출 시점에 알아서 객체 래퍼를 박싱해주기 때문에 객체 래퍼로 감싸지 않아도 해당 메서드를 호출하고 사용할 수 있다.
#
how can toString()?여기서 보면 prototype
얘기가 많이 나오는데 이후에도 배우겠지만, prototype
프로퍼티는 자바스크립트 내부에서도 굉장히 광범위하게 사용된다.
모든 내장 생성자 함수에서는 prototype
프로퍼티를 정보를 참조해서 사용하고 있다.
위에 처럼 빈 객체를 만들면 toString() 메서드를 호출할 수 있는 이유는 prototype
안에 다양한 메서드가 구현되어있는 거대한 객체를 참조할 수 있기 때문이다.
즉, obj.toString()
을 호출하면 Object.prototype
에서 해당 메서드를 가져오게 되고 해당 메서드를 호출하게 되는것이다.
주의할점은 obj.__proto__
는 메서드 체이닝이 없다는 점이 있다.
결국 원시타입에서 해당 타입이 지원하는 메서드를 사용가능한 것은 호출시점에 자바스크립트 엔진이 해당 타입의 객체 레퍼를 감싸주면서 Object(그외 다양한 타입).prototype
에 구현되어있는 정보를 참조해서 사용할 수 있는것이다.
#
다양한 내장 객체의 prototype간단한 예시로 배열 [1, 2, 3]
을 만들면 new Array()
의 디폴트 생성자가 내부에서 동작하여 Array.prototype
이 배열 [1, 2, 3]
의 프로토타입이 되고 개발자는 Array.prototype
을 통해 배열 메서드를 사용할 수 있는 것이다.
이런 내부 동작은 자바스크립트 엔진 환경에서 메모리 효율을 높여주는 장점이 있기도 하다.
그리고 상속 트리 꼭대기엔 꼭대기엔 Object.prototype
이 있어야 한다고 명세서에서 규정하고 있는데, 이런 명세 때문에 몇몇 사람들은 "모든 것은 객체를 상속받는다." 라는 말을 하기도 하는 것 같다.
#
체인상에 중복 메서드?생각을 해보면 상속 관계상 체인상에 중복 메서드가 있을 수 있다.
Array.prototype
엔 요소 사이에 쉼표를 넣어 요소 전체를 합친 문자열을 반환하는 자체 메서드 toString()
있다.
그런데 Object.prototype
에도 메서드 toString()
이 있는데, 이렇게 중복 메서드가 있을 때는 체인 상에서 가까운 곳에 있는 메서드가 호출된다.
#
원시값 프로토타입사실 원시값 중 문자열과 숫자, 불린값은 객체가 아니다. 그런데 이런 원시 타입 값의 프로퍼티에 접근하려고 하면 내장 생성자 String
, Number
, Boolean을
사용하는 임시 래퍼(wrapper) 객체가 생성된다.
임시 래퍼 객체는 이런 메서드를 제공하고 난 후에 사라진다.
래퍼 객체는 보이지 않는 곳에서 만들어지는데 엔진에 의해 최적화가 이뤄지기 때문에 효율적으로 사용이 가능한 것.
실제로 우리가 자바스크립트에서 리터럴 표현식으로 편하게 문법을 사용할 수 있는것도 이런 최적화와 지원이 있기 때문.
note
null
과 undefined
에 대응하는 래퍼 객체는 없다.
특수 값인 null
과 undefined
는 문자열과 숫자, 불린값과는 다르다.
null
과 undefined
에 대응하는 래퍼 객체는 없다.
따라서 null
과 undefined
에선 메서드와 프로퍼티를 이용할 수 없으며, 프로토타입도 사용할 수 없다.
#
마무리어차피 모두 책을 읽고 내용을 알고있다고 생각이 되서 조금 더 깊은 내용을 정리해보았다.
확실히 내부적인 동작방식을 보면서 자바스크립트는 프로토타입 언어라고 아예 책 제목을 가진 책들도 있는데 점점 공감이 간다.
각 네이티브 타입의 프로토타입을 직접 추가하거나 선언하면 해당 타입을 호출할 때 사용할 수도 있는데, 그럴경우 다른 라이브러리나 프로토타입 명세를 덮어씌울 수 있다고 하니 절대 권장하지 않는다.