[Javascript] 프로토타입 체인

Bam·2022년 2월 26일
0

Javascript

목록 보기
55/106
post-thumbnail

상속에 대하여...

우선 상속이라는 객체지향의 개념에 대해 알아보겠습니다. 상속은 어떤 클래스나 객체의 프로퍼티/메소드를 또 다른 객체가 이어받아 새로운 클래스/객체가 마치 자기것 처럼 사용하는 것을 의미하는 객체지향 프로그래밍의 용어입니다.

상속에서 상속을 해주는 클래스를 부모 클래스, 슈퍼 클래스, 베이스 클래스, 상위 클래스라고 하고 상속을 받는 클래스를 자식 클래스, 서브 클래스, 파생 클래스, 하위 클래스라고 부릅니다. 앞으로 저는 부모-자식 클래스라는 용어를 가지고 사용하도록하겠습니다.

상속이 아직 감이 잘 안잡히시나요? 한 가지 예를 들겠습니다.
스마트폰과 공중전화기는 둘 다 전화기라는 공통을 갖고있습니다. 만약 스마트폰과 공중전화기 두 객체를 만든다면 똑같이 전화걸기, 전화받기라는 공통적인 행동(메소드)을 갖고 있는데, 이 똑같은 행동(메소드)을 두 객체에 담으면 같은 코드가 두 번 사용되어 코드가 길어지고, 작성 효율이 떨어지는 것을 보입니다. 그래서 전화걸기와 받기라는 메소드를 담은 전화기 클래스를 정의하고 스마트폰과 공중전화기에 상속을 시키면 두 객체에서 전화걸기와 받기라는 동일메소드를 따로 선언하지 않아도 되게 됩니다. 이때, 전화기 클래스는 부모, 스마트폰/공중 전화기 클래스는 자식 클래스가 됩니다.

이처럼 작성효율도 높아지고 코드도 분리되어 유지보수가 좋다는 장점을 갖습니다.

또한, 자식 클래스는 부모 클래스로부터 받은 프로퍼티와 메소드를 오버라이딩(재정의)할 수 있습니다. 오버라이딩은 프로퍼티/메소드의 이름을 유지한 채로, 기능만 바꾸는 것을 의미합니다.

상속은 이쯤하고 자바스크립트의 개념인 프로토타입 체인으로 넘어가보겠습니다.

프로토타입 체인

자바스크립트는 프로토타입 기반 언어이므로, 상속 개념 또한 엄밀히 말하면 존재하지 않는다고 할 수 있습니다. 하지만 프로토타입 체인이라고하는 상속과 유사한 개념이 존재합니다.

let Phone = function () {};	//부모 클래스 Phone과 생성자

Phone.prototype.getCall = function () { //Phone 프로토타입 메소드 정의
    return '전화 받기';
}

let SmartPhone = function () {  //자식 클래스 SmartPhone
    Phone.call(this);	//Phone클래스 생성자를 자식 클래스에서 호출
}

SmartPhone.prototype = new Phone();	//프로토타입 체인

let smartPhone = new SmartPhone();	//전화기 클래스를 상속받은 스마트폰 객체 생성

console.log(smartPhone.getCall());

코드를 한 줄 한 줄 뜯어보겠습니다.

먼저 Phone이라는 프로토타입을 생성하고, 그 멤버로 getCall이라는 메소드를 추가했습니다.
그 다음 자식 클래스가 될 SmartPhone 프로토타입을 생성합니다. 이때 부모 클래스가 될 Phone의 생성자를 call메소드를 통해 호출합니다.
그리고 자식 클래스에 prototype프로퍼티를 통해 Phone 프로토타입과 체인을 걸어줍니다.
마지막으로 smartPhone 객체를 생성하고 getCall을 하니, smartPhone 객체에 없는 메소드임에도 불구하고 체인으로 연결된 부모 클래스의 getCall 메소드가 정상적으로 실행이 되었습니다.

이것이 프로토타입 체인입니다. 객체지향언어들이 extends키워드를 통해 간단하게 상속을 하는 반면, 프로토타입 체인은 조금 복잡해보입니다. 하지만 생긴거에 비해 금방 적응되니 걱정하지 않으셔도 됩니다.

멤버 추가와 오버라이딩

그러면 프로토타입 체인에서 멤버 추가와 오버라이딩도 한 번 수행해보겠습니다.

let Phone = function () {
};

Phone.prototype.getCall = function () {
    return '전화 받기';
}

let SmartPhone = function () {
    Phone.call(this);
}

SmartPhone.prototype = new Phone();
SmartPhone.prototype.getCall = function () {	//getCall() 메소드 오버라이딩
    return '스마트폰 전화 받기';
};
SmartPhone.prototype.playMusic = function () {	//메소드 추가
  return '음악 재생';
};

let smartPhone = new SmartPhone();

console.log(smartPhone.getCall());
console.log(smartPhone.playMusic());

0개의 댓글