객체 형태의 데이터 집합으로, 원형(prototype)객체를 위임하여 객체지향 프로그래밍을 가능하게 해준다.
간단하게 객체가 가진 속성의 모임이 프로토타입이다.
자바스크립트는 초기에 Class
를 지원하지 않았고 객체지향 프로그래밍을 구현하기 위해 prototype을 이용하 였다.
prototype이라는 프로퍼티는 function에서만 존재한다.
프로토 타입은 어떤 식으로 이루어져있는지 먼저 살펴보면
function Person (name) {
this.name = name
}
console.dir(Person)
/*
f Person(name)
...
prototype:
constructor: f Person (name)
__proto__ : Object
__proto__ : f ()
...
*/
다음과 같은 결과를 확인 할 수 있다.
Person
이라는 함수는 Function
의 Prototype을 상속 받았으며, 프로토 타입을 상속해 줄수 있다
let dave = new Person('dave')
console.dir(dave)
/*
Person
name: "dave",
__proto__:
constructor: ƒ Person(name)
__proto__:object
....
*/
실제로 new
키워드를 통해 상속받은 dave
라고 하는 객체는 __proto__
의 객체가 Person.prototype
과 같다
dave.__proto__ === Person.prototype
class를 상속하여 확장하는데 있어서 중요한 역할을 하게 된다.
function Book (name, author) {
this.name = name;
this.author = author;
}
Book.prototype.sell = function () { console.log('++$$') }
Book.prototype.fame = function () { console.log('~ing') }
console.dir(Book)
/*
...
..
prototype:
constructor: f Book()
fame: f()
sell: f();
__proto__: ...
...
*/
const comics = new Book('comics', 'owner');
comics.name // 'comics'
comics.sell // '++$$'
comics.fame // '~ing'
console.dir(comics)
/*
name : 'comics',
author:
...
__proto__:
fame: f()
sell: f()
constructor: f Book()
__proto__: ...
*/
prototype
에는
constructor
로 Book
이라는 함수,
sell
이라는 메서드와
fame
이라는 메서드가 존재한다.
상속을 받은 객체는 (comics
) 실제로 함수(Book
)의 prototype을 상속 받게 된다.
실제로 인스턴스를 생성할 때도 일어나지만 다른 클래스를 만들때도 같은 방식으로 작동하게 된다.
// 부모 클래스
function Book (name, author) {
this.name = name; // name 속성
this.author = author; // author 속성
}
Book.prototype.sell = function () { console.log('++$$') } // sell 메서드
Book.prototype.fame = function () { console.log('~ing') } // fame 메서드
// 부모를 상속받을 새로운 클래스
function Comics (name, author, genre) {
Book.call(this, name, author) // 상속받은 속성
this.genre = genre; // 새로운 속성 추가
}
Comics.prototype = Object.create(Book.prototype) // prototype 상속
Comics.prototype.constructor = Comics // 생성자 함수 설정
Comics.prototype.sell = function () {
Book.prototype.sell.apply(this) // 상속받은 클래스의 기능 실행
console.log('+++++++++$$$$'); // 확장 기능 추가
}
Comics.prototype.laugh = function () { console.log('hahaha!!!') } // 새로운 메서드
코믹스를 객체가 아닌 새로은 클래스를 생성하는 코드를 작성해 보았다.
실제로 constructor를 설정해 주기 위해
comics function
을 구현하고 이번엔 genre
를 추가 해주었다.
Book클래스
를 상속을 위해 Book.call(this,name,author)
를 통해 this.genre
로 새로운 속성을 추가해 주었다.
프로토타입 상속을 위해
Comics.prototype = Object.create(Book.prototype)
을 추가해서 Comics가 Book의 프로토타입을 상속하도록 구현할 수 있다.
Comics.prototype.constructor = Comics
생성자를 Comics로 설정해
실제로 어떤 클래스로 인스턴스를 생성하는지 어떤 클래스로 부터 상속 받는지 명시해 주게 된다.
실제로 Class
키워드를 사용하면 더 쉽게 구현이 가능하다.
class Book {
constructor(name, author) {
this.name = name;
this.author = author;
}
sell () {
console.log(`${this.name}++$$`) // 이번엔 인스턴스의 이름을 출력하게 변경
}
fame () {
console.log('~ing')
}
}
// Comics는 Book을 상속받은 클래스 입니다.
class Comics extends Book {
constructor(name,author,genre) {
super(name,author) // 기존 생성자 속성을 가지고 옵니다.
this.genre = genre; // 새로운 속성을 추가 합니다.
}
sell () {
super.sell.apply(this) // 상속받은 메서드를 실행합니다.
console.log('++++++++++$$$$$$$$') // 기능을 추가해 확장 합니다.
}
laugh () {
console.log('hahahahahaha') // 새로운 기능 입니다.
}
}
자바스크립트는 ES6부터 class 키워드를 통해 클래스 생성을 지원 하였고 이전에는 prototype 기반 프로그래밍을 통해 클래스를 구현하여 객체지향 프로그램밍을 구현했다.
현재는 class를 통해 객체지향 프로그래밍을 하고 있는 추세지만 아직 prototype을 사용 할 수 있으니 알아 두는게 좋다.