프로토타입이란
class를 만들고 class를 extends 한는 것처럼 프로토타입을 통해서 상속을 구현할 수 있다.
Prototype-based Programming
프로토타입을 기반으로 한 프로그래밍 언어라는 것은 객체지향 프로그래밍을 할 수 있는 방식으로써 행동을 재사용할 수 있고 object를 재사용할 수 있다. 그리고 이것을 바로 prototype을 통해 구현한다.
const a = {};
const b = {};
console.log(a); // [[Prototype]]: Object
console.log(b); // [[Prototype]]: Object
console.log(a.__proto__ === b.__proto__); // true
객체를 콘솔에 출력해 모드 확장해 보면 Object 라는 prototype 을 확인할 수 있다. 이 말은 모든 객체는 Object 라는 프로토타입을 상속한다는 의미이며 그렇기 때문에 모든 객체에서 toString, keys, ... 등과 같은 메소드들을 사용할 수 있는 것이다. a
와 b
의 프로토타입을 비교했을 때 true
가 출력되는데, 객체들은 같은 하나의 프로토타입을 상속받기때문이다.
그렇다면 배열은 어떨까?
const array = [];
console.log(array); // [[Prototype]]: Array
배열 또한 Object와 다르지 않다. Array 라는 프로토타입을 상속한다. 여기서 살펴볼 점은 배열 또한 객체에 속하기 때문에 Array 라는 프로토타입 안에 Object 라는 프로토타입이 상속되어있는 것을 알 수 있다. 객체의 메소드인 toStirng 과 같은 메소드를 배열에서도 사용할 수 있는 이유이다.
예제로 쉽게 이해하기
prototype의 사용에 대하여 간단한 예제를 들어보자.
동물의 정보를 받고 해당 동물의 소리를 만드는 함수가 있다고 가정할 한다.
function Animal(animal) {
this.animal = animal;
this.makeSound = (animal) => {
console.log(`make sound to ${animal}`);
};
}
const dog = new Animal('dog');
const cat = new Animal('cat');
console.log(dog);
console.log(cat);
함수를 실행하고 출력하면, 이와 같이 출력되는것을 확인할 수 있다.
animal
과 makeSound
는 만들어지는 Instance 마다 포함된다. 이를 Instance member level 이라고 부르는데 우리는 이것을 prototype을 통해 공통적으로 사용되는 makeSound를 상속할 수 있도록 개선해볼 것이다.
▾ Animal
animal: 'dog'
makeSound: ...
▾ Animal
animal: 'cat'
makeSound: ...
공통적으로 사용하는 makeSound
함수를 prototype으로 분리했다.
function Animal(animal) {
this.animal = animal;
}
Animal.prototype.makeSound = (animal) => {
console.log(`make sound to ${animal}`);
};
const dog = new Animal('dog');
console.log(cat);
출력해보면 makeSound가 아닌 프로토타입이 함께 출력된 것을 볼 수 있다.
▾ Animal
animal: 'dog'
▸[[Prototype]]: Object
이번에는 동물이 아닌 사람의 사람의 소리를 만드는 함수 만들었다.
function Person(person} {
this.person = pserson;
}
Person.prototype = Object.create(Animal.prototype);
const minsoo = new Person('minsoo');
minsoo.makeSound('minsoo');
정말 간단하다! Animal
의 프로토타입을 상속해 makeSound
를 사용할 수 있게 되었다. 이처럼 상속과 재사용을 프로토타입을 통해 구현할 수 있다. 출력 결과는 이와 같다.
▾ Person
animal: 'minsoo'
▸[[Prototype]]: Object
'make sound to minsoo'