[JS] 프로토타입

강원지·2023년 5월 17일
0

프로토타입

자바스크립트에서 객체지향 프로그래밍의 개념을 사용할 수 있도록 도와주는 메커니즘.

자바스크립트는 프로토타입을 기반으로 상속을 구현한다. 프로토타입은 어떤 객체의 상위 객체의 역할을 하는 객체로서 다른 객체에 공유 프로퍼티를 제공한다. 따라서 프로토타입을 상속받은 자식 객체는 부모 객체의 프로퍼티를 자유롭게 사용할 수 있다.
상속을 통해 기존 코드를 적극적으로 활용하여 불필요한 중복을 제거할 수 있다.

function Movie(name, charaters) {
  this.name = name;
  this.charaters = charaters;
  Movie.prototype.printCharacter = function () {
    console.log(this.charaters);
  };
}
const 미니언 = new Movie("미니언즈", ["밥", "데이브"]);
미니언.printCharacter();

const 스폰지밥 = new Movie("스폰지밥", ["스폰지밥", "뚱이", "징징이"]);
스폰지밥.printCharacter();

접근자 프로퍼티

모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입인 [[ Prototype ]] 내부 슬롯에 간접적으로 접근할 수 있다.

모든 객체가 __proto__ 접근자 프로퍼티를 사용할 수 있는 것은 아니다. (ex. Object.create(null): 프로토타입 체인의 종점)
따라서 __proto__ 접근자 프로퍼티 대신 Object.getPrototypeOf와 Object.setPrototypeOf 사용을 권장한다.

프로토타입 체인

new 연산자를 사용해 생성한 객체는 생성자의 프로토타입을 자신의 프로토타입으로 상속받는다.

var obj = new Object(); //Object.prototype
var arr = new Array();  //Array.prototype
var date = new Date(); //Date.prototype, Object.prototype

프로토타입 다루기

객체 생성자 함수를 사용하여 같은 프로토타입을 가지는 객체들을 생성할 수 있다. 또, prototype 프로퍼티를 이용하면 기존 프로토타입에 새로운 프로퍼티나 메소드를 추가할 수 있다.

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
}

// 현재 존재하고 있는 Dog 프로토타입에 family 프로퍼티를 추가함.
Dog.prototype.family = "시베리안 허스키";

// 현재 존재하고 있는 Dog 프로토타입에 breed 메소드를 추가함.
Dog.prototype.breed = function() {
    return this.color + " " + this.family
};

var myDog = new Dog("흰색", "마루", 1);
var hisDog = new Dog("갈색", "콩이", 3);

효과적인 프로토타입 사용법

상속 흉내내기
하위 객체로 이용할 생성자 함수를 만든 후, 해당 생성자 함수의 프로토타입으로 상위 객체를 대입한다. 상위 객체의 함수가 링크되어 그대로 사용 가능할 수 있다.

내부적으로 생성된 프로토타입 변수는 사용할 수 없다.

function Movie(name, charaters) {
  this.name = name;
  this.charaters = charaters;
}
Movie.prototype.printCharacter = function () {
  console.log(this.charaters);
};
Movie.prototype.getName = function () {
  return this.name || "영화 제목";
};

function Animation(name, charaters) {}
Animation.prototype = new Movie();

const 미니언 = new Movie("미니언즈", ["밥", "데이브"]);
미니언.printCharacter(); //[ '밥', '데이브' ]
console.log(미니언.getName()); //미니언즈

const 스폰지밥 = new Animation("스폰지밥", ["스폰지밥", "뚱이", "징징이"]);
스폰지밥.printCharacter(); //undefined
console.log(스폰지밥.getName()); //영화 제목

해결방법

문제 : 내부적으로 생성된 프로토타입 변수는 사용할 수 없다.

⇒ 부모 생성자를 빌리면 사용할 수 있다.

function Animation(name, charaters) {
 // Movie 생성자 함수를 현재 객체(this)에 적용하여 속성을 설정
 // 부모의 생성자 호출
 Movie.apply(this, arguments);
}

Animation.prototype = new Movie(); 

const 스폰지밥 = new Animation("스폰지밥", ["스폰지밥", "뚱이", "징징이"]);
스폰지밥.printCharacter(); //[ '스폰지밥', '뚱이', '징징이' ]
console.log(스폰지밥.getName()); //스폰지밥

참고
[Javascript] 프로토타입 이해하기
JavaScript | 프로토타입 Prototype
프로토타입과 프로토타입 체인
TCP school 프로토타입

0개의 댓글