[JavaScript] 객체 지향_프로토타입(Prototype)과 프로토타입 체인

Seungmin Lee·2022년 7월 22일
0

JavaScript

목록 보기
12/14
post-thumbnail

프로토타입을 공식문서에 찾아보면 원형객체 어쩌고 하는데 그냥 상속받은 부모의 유전자 라고 생각하면 쉽다.

prototype__proto__

아래의 코드는 Hero라고 하는 객체를 만드는 생성자함수, 한마디로 객체 만드는 기계를 구현한 코드이다.

// ES5
function Hero(skil1, skil2){
  this.q = skil1;
  this.w = skil2;
}

이 때, Hero객체가 만들어지면서 Hero의 prototype이라는 객체가 몰래? 생성된다. 이 두 객체는 이름만 봐도 서로 관련이 있다는 것을 알 수 있기 때문에 서로를 알 수 있는 방법이 필요하다.

사실 처음 Hero 객체가 만들어질 때 prototype이라는 속성을 이미 갖게 되고, 이 prototype속성을 통해서 Hero의 prototype객체를 참조할 수 있게 된다.

그리고 Hero의 prototype객체Hero객체의 소속이라는 것을 constructor라는 속성을 만들어서 기록하고 Hero객체를 가르키게 된다.

아래의 코드는 Hero의 prototype의 속성에 e속성을 추가하는 코드이다.

// ES5
function Hero(skil1, skil2){
  this.q = skil1;
  this.w = skil2;
}

Hero.prototype.e = function(){}
let yumi = new Hero('syarere', 'yumirang')

생성자를 통해 yumi라는 객체를 만들면 q, w속성과 함께 __proto__ 라는 속성이 보이지는 않지만 함께 생기게 된다. 이 때, __proto__라는 속성은 Hero의 prototype 즉, 부모의 유전자를 가르킨다.

따라서 Hero.prototype, yumi.__proto__ 둘 다 Hero의 prototype을 참조하는 방법이 된다.

function Hero(skil1, skil2){
  this.q = skil1;
  this.w = skil2;
}
//Hero의 프로토타입 속성에 e속성을 추가
Hero.prototype.e = function(){}

console.log(yumi.e) // f(){}

위 코드에서 yumi 객체는 직접 e속성을 갖지 않지만 콘솔에 찍어보면 에러가 뜨지 않고 함수를 출력한다.

그 이유는 yumi__proto__속성이 Hero.prototype을 참조하고 있기 때문이다.

프로토타입 체인과 상속

프로토타입 체인이라는 개념이 있기 때문에 OOP의 특징 중 하나인 상속이 가능하고 class syntax에서는 extends, super와 같은 키워드를 사용한다. 이 때, 속성과 메서드를 물려주는 클래스를 부모 클래스, 물려받는 클래스를 자식 클래스라고 한다.

조회하고자 하는 속성을 해당 객체가 직접 가지고 있다면 조회할 수 있겠지만 없다면 어떻게 작동할까? 찾는 값이 없다면 이제 이 유전자라고 했던 프로토타입을 들여다 보는 것이다. 그리고 프로토타입의 속성 중에 내가 찾는 속성이 있다면 그 속성을 가져 올 수 있다. 하지만, 만약 부모의 프로토타입에도 없다면 부모의 부모를 조회하고, 또 없다면 부모의 부모의 부모... 이런식으로 계속 타고 올라가서 찾을 것이고 마지막까지 없다면 그 속성은 없다고 할 것이다. 이것이 상속의 작동 원리이고 프로토타입 체인(Prototype Chain)이다.

class syntax 와 상속

// 부모 클래스
class Hero{
  constructor(skil1, skil2){
    this.q = skil1;
    this.w = skil2;
  }
  message(){
    return `${this.skil1} 스킬 사용 ${this.skil2} 스킬 사용`
  }
}

// 자식 클래스 
class newHero extends Hero{ // extends 키워드
  constructor(skil1, skil2, skil3){
    super(skil1, skil2); // super 키워드
    this.e = skil3;
  }
  message(){ // super 키워드
    return super.message() + `${this.skil3} 스킬 사용`
}
  • newHero extends Hero : Hero를 확장해서 newHero를 만들자
  • super() : 부모 클래스의 생성자(constructor) 호출
  • super.message() : 부모 클래스의 message 함수 호출
profile
<Profile name="seungmin" role="frontendDeveloper" />

0개의 댓글