thisyujeong.dev

프로토타입(Prototype) 이해하기
June 5, 2021

프로토타입이란

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, ... 등과 같은 메소드들을 사용할 수 있는 것이다. ab 의 프로토타입을 비교했을 때 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);

함수를 실행하고 출력하면, 이와 같이 출력되는것을 확인할 수 있다.
animalmakeSound 는 만들어지는 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'