본문 바로가기

WEB/JavaScript

프로토타입 체이닝(2)

래퍼 객체(Wrapper Object)

자바스크립트에서 문자열이나 숫자에서 메서드를 사용할 수 있는 이유는 기본 타입(number, string, boolean, null, undefined, symbol)에서 숫자와 문자열, 불린, 심볼 타입에 대응하는 래퍼 객체(Number, String, Boolean, Symbol)가 지원되기 때문이다.(래퍼 객체는 보통 표준 내장 객체(standard buit-in object)라고 불린다.)

만약 자바스크립트에서 string 타입 데이터에서 메서드나 프로퍼티를 참조하려고 할 때, 자바스크립트는 string 타입 데이터를 String 래퍼 객체로 임시로 변환해서 메서드나 프로퍼티를 참조할 수 있게 한다. 따라서 문자열에서 String.prototype 객체의 프로퍼티들을 모두 사용할 수 있게 된다. 하지만 이렇게 임시로 생성된 객체는 참조가 끝나면 소멸하게 된다.

이렇게 기본 타입에 프로퍼티를 생성해도 임시로 생성되는 래퍼객체에 대신 생성되기 때문에 기본 타입에는 프로퍼티를 생성할 수 없다.

추가로 변수에 정수를 담지 않고 바로 Number.prototype 객체에 정의된 프로퍼티를 사용할 때, 에러가 나는 상황이 있을 것이다.

이 경우에는 자바스크립트에서 1. 을 참조 연산자가 아닌 소수를 표현하는 키워드로 인식하기 때문에 정수에서 표준 메서드를 사용하려면 밑의 코드처럼 작성해야 한다. (사실 이 문제는 정수 값을 변수에 담아서 사용하면 발생하지 않는 문제이다.)

표준 내장 객체의 프로토타입 객체

내장 객체(Number, String 등)도 객체이기 때문에 프로토타입 객체가 있다. 자바스크립트에서는 표준 내장 객체의 프로토타입 객체에 프로퍼티나 메서드를 추가하는 것이 가능하다. 만약 Number 객체의 프로토타입 객체에 메서드를 추가하면 표준 메서드처럼 모든 숫자 타입 데이터에서 사용할 수 있다.

프로토타입 객체의 프로퍼티 변경

함수가 생성될 때 prototype 프로퍼티로 연결되는 프로토타입 객체는 기본으로 constructor 프로퍼티를 가지는 객체다. 프로토타입 객체도 일반 객체같이 똑같은 객체이기 때문에 프로퍼티를 변경할 수 있다. 이렇게 변경된 프로토타입 객체의 프로퍼티는 실시간으로 프로토타입 체이닝에 적용된다.

프로토타입 객체 메서드와 this 바인딩

앞서 말했듯이 프로토타입 객체도 객체이기 때문에 프로퍼티와 메서드를 가질 수 있다. 여기서는 프로토타입 객체의 메서드를 프로토타입 메서드라고 할 것이다. 만약 프로토타입 메서드 내부에서 this를 사용하게 된다면 이 this는 어디에 바인딩될까? 이는 앞에서 말했던 this 바인딩 규칙을 그대로 따르게 된다.

위에서 볼 수 있듯이 Animal.prototype 객체에서 getSpecies 함수를 호출하면 this가 Animal.prototype 객체에 바인딩되고, frog 객체에서 getSpecies 함수를 호출하면 this가 frog 객체에 바인딩 된다. 이를 통해서 프로토타입 체이닝을 통해서 부모의 메서드를 호출하게 된다면 this는 메서드를 호출한 자식 객체에 바인딩된다는 사실을 알 수 있다.(물론 프로토타입 체이닝이 아니라 직접 프로토타입 객체에서 메서드를 호출하면 프로토타입 객체 자신에게 this가 바인딩 된다.)

디폴트 프로토타입 객체의 변경

디폴트 프로토타입 객체는 함수가 생성될 때 같이 생성된다. 자바스크립트에서는 이렇게 함수를 생성할 때 함께 생성되는 디폴트 프로토타입 객체를 다른 객체로 변경할 수 있다.

하지만 생성자 함수의 프로토타입 객체가 변경되면, 변경된 이후로 생성되는 객체와 변경되기 전에 생성된 객체는 서로 다른 프로토타입 객체와 연결된다. 프로토타입 객체가 변경된 이후에 생성된 객체는 새로운 프로토타입 객체와 [[Prototype]] 프로퍼티로 연결되지만, 이전에 생성된 객체는 자신이 생성될 때 연결된 프로토타입 객체와의 링크를 유지한다. 코드를 통해서 자세히 알아보자.

위 코드를 보면 알 수 있듯이 생성자 함수의 프로토타입 객체가 달라지면 달라지기 이전에 생성자 함수로 생성된 객체와 달라진 이후에 생성된 객체는 서로 다른 프로토타입 객체(부모 객체)를 가지게 된다.

'WEB > JavaScript' 카테고리의 다른 글

typeof 연산자  (0) 2018.06.15
실행 컨텍스트(1)  (0) 2018.05.31
프로토타입 체이닝(1)  (0) 2018.05.20
JS의 데이터 타입 5 (함수)  (0) 2018.05.17
JS의 데이터 타입 4 (함수)  (0) 2018.05.06