본문 바로가기

자바스크립트

[Javascript] - 네이티브 프로토타입

 

Object.prototype

 

-  obj는 빈 객체인데 [object Object] 문자열을 생성하는 toString()은 어디에 있는 걸까

-  obj = new Object()를 줄이면 obj = {} 가 된다 여기서 Object는 내장 객체 생성자 함수인데 이 생성자 함수의 prototype은 toString을 비롯한 다양한 메서드가 구현되어 있는 거대한 객체를 참조한다.

 

 

- new Object()를 호출하거나 리터럴 문법 {}을 사용해서 객체를 만들때 새롭게 생성된 객체의 [[Prototype]] 은 이전 챕터에서 언급한 규칙에 따라 Object.prototype을 참조한다.

 

- 따라서 obj.toStirng()를 호출하면 Object.prototype에서 해당 메서드를 가져오게 된다.

 

- 위 예제를 보면 좀 더 명확하게 확인할 수 있다.

-  이때 주의할 점은 Object.prototype 위의 체인엔 [[Prototype]]이 없다는 점을 주의해야 한다.

 

다른 내장 프로토타입

 

- Array, Date, Function 을 비롯한 내장 객체들 역시 프로토타입에 메서드를 저장해 놓는다.

- 배열 [1, 2, 3] 을 만들면 기본 new Array() 생성자가 내부에서 사용되기 때문에 Array.prototype이 배열 [1, 2, 3]의 프로토타입이다 Array.prototype은 배열 메서드도 제공한다 이런 내부 동작은 메모리 효율을 높여주는 장점을 가져다 준다.

 

 

 - 명세서에서는 모든 내장 프로토타입 꼭대기엔 Object.prototype이 있어야 한다고 규정한다 이런 규정 때문에 몇몇 사람들은 모든 것은 객체를 상속받는다 라는 말을 한다.

 

 

- 체인 상의 프로토타입엔 중복 메서드가 있을 수 있다 Array.prototype 엔 요소 사이에 쉼표를 넣어 요소 전체를 합친 문자열을 반환하는 자체 메서드 toString이 있다.

 

- 그런데 Object.prototype에도 tostring이 있다 이렇게 중복 메서드가 있을 때는 체인 상에 가까운 곳에 있는 메서드가 사용된다.  Array.prototype이 체인상에서 더 가깝기 때문에 Array.prototype의  toString이 사용된다.

 

- chrome 개발자 콘솔과 같은 도구를 사용하면 상속관계를 확인할 수 있다 console.dir을 사용하면 내장 객체의 상속 관계를 확인하는데 도움이 된다.

 

- 배열이 아닌 다른 내장 객체들 또한 같은 방법으로 동작한다 함수도 마찬가지다 위 예제를 보면 함수는 내장 객체 Function의 생성자를 통해 만들어지는데 call, apply를 비롯한 함수에서 사용할 수 있는 메서드는 Function.prototype에서 가져온다 함수에도 toString이 구현되어 있다.

 

원시값

- 문자열과 숫자 불린값을 다루는 것은 엄청 까다롭다.

- 문자열과 숫자 불린값은 객체가 아니다 그런데 이런 원시값들의 프로퍼티에 접근하려고 하면 내장 생성자 String, Number, Boolean을 사용하는 임시 래퍼 객체가 생성된다 임시 래퍼 객체는 이런 메서드를 제공하고 난 후 사라진다

- 래퍼 객체는 보이지 않는 곳에서 만들어진다 최적화는 엔진이 담당한다 그런데 명세서에선 각 자료형에 해당하는 래퍼 객체의 메서드를 프로토타입으로 구현해놓고 prorototype을 사용해 쓸 수 있도록 규정한다.

- 참고로 특수값인 null과 undefined는 대응하는 래퍼객체가 존재하지 않는다.

 

네이티브 프로토타입 변경하기

 

 

- 위 예제에서 네이티브 프로토타입을 수정할 수 있다 String.prototype 에 메서드를 하나 추가하면 모든 문자열에서 해당 메서드를 사용할 수 있다.

 

- 하지만 위와 같이 네이티브 프로토타입에 새 내장 메서드를 추가하는 것은 좋지 못하다 왜냐하면 프로토타입은 전역으로 로 영향을 미치기 때문에 프로토타입을 조작하면 충돌이 날 가능성이 매우 높다.

 

- 만약 두 라이브러리에서 동시에 String.prototype.show 메서드를 추가하면 한 라이브러리의 메서드가 다른 라이브러리의 메서드를 덮어 쓴다 이런 이유로 네이티브 프로토타입을 수정하는 것은 추천하지 않는다.

 

 

- 모던 프로그래밍에서 네이티브 프로토타입 변경을 허용하는 경우는 딱 하나뿐이다 바로 풀리필을 만들 때이다 풀리필은 자바스크립트 명세서에 있는 메서드와 동일한 기능을 하는 메서드 구현체를 의미한다 명세서에는 정의되어 있으나 특정 자바스크립트 엔진에서는 해당 기능이 구현되어 있지 않을 때 풀리필을 사용한다.

 

프로토타입에서 빌려오기

 

- 개발을 하다보면 네이티브 프로토타입에 구현된 메서드를 빌려야 하는 경우가 종종 생긴다.

 

 

- 위 예제는 유사 배열 객체를 만들고 여기에 Array 메서드를 복사했다.

- 예시를 실행하면 에러 없이 의도한 대로 동작한다 내장 메서드 join의 내부 알고리즘은 제대로 된 인덱스가 있는지와 length 프로퍼티가 있는지만 확인하기 때문이다 호출 대상이 진짜 배열인지는 확인하지 않는다 다수의 내장 메서드가 이런 식으로 동작한다.

 

- 메서드 빌리기 말고도 obj_proto_를 Array.prototype으로 설정해 배열 메서드를 상속하는 방법이 있다.

- 하지만 이러한 방식은 만약 obj가 다른 객체를 상속받고 있을 때는 사용할 수 없다.