Front-end/JavaScript

JS 프로토타입 1편 - 프로토타입 상속

파리외 개발자 2023. 1. 21. 20:04

프로토타입 상속

let dragon = {
  name: "Red dragon",
  fire: true,
  fight() {
    return 100;
  },
  sing() {
    if (this.fire) {
      return `I am ${this.name} the breather of fire`;
    }
  },
};

드래곤 객체는 변수 2개와 메서드 2개를 가지고 있다.

let lizard = {
  name: "sand lizard",
  fight() {
    return 1;
  },
};

const signLizard = dragon.sing.bind(lizard);
console.log(signLizard());

도마뱀 객체는 드래곤의 열화판으로 멤버변수와 메서드의 이름은 같고 내용은 다르다.

bind를 사용해 드래곤의 sing메서드를 빌려서 사용해 본다.

실행은 되었지만 아무 일도 일어나지 않았다.

이유는 sing메서드는 호출한 객체에 fire값이 true이어야 하는데

도마뱀 객체는 fire 멤버 변수를 가지고 있지 않기 때문이다.

반면 dragon객체에서 sing메서드를 실행시키면 this가 가리키는 것은 dragon객체이기 때문에

this.fire는 true값을 가지면서 메서드의 내용이 실행된다.

//상속
lizard.__proto__ = dragon;
//드래곤은 도마뱀의 프로토타입이다.
dragon.isPrototypeOf(lizard);
lizard.name;
lizard.fire;
lizard.fight();
lizard.sing();

bind 말고 프로토타입 상속을 시켜줬다.

 

isPrototypeOf메서드는 인자로 전달받은 개체가 호출한 개체의 프로토타입인지를 불린값으로 리턴한다.

프로토타입 상속을 시켜주면 lizard에 존재하는 멤버는 자신의 것을 가져와서 사용하고

자신에게 존재하지 않는 멤버는 상속받은 객체인 dragon의 것을 가져와서 사용한다.

여기서 특이한 것은 dragon의 메서드를 상속해서 가져오더라도

실행한 객체는 lizard이기 때문에 this는 lizard를 가리키고

자신의 이름으로 된 sing메서드를 실행하게 된다.

for (let p in lizard) {
  console.log("all props : " + p);
  if (lizard.hasOwnProperty(p)) {
    console.log("own props : " + p);
  }
}

반복문을 통해 lizard객체가 가진 모든 멤버와

자신만의 멤버를 출력해 본다.

lizard는 네 개의 속성을 가지지만

hasOwnProperty로 자신만의 속성을 걸러내면 name과 fight만 있는 것을

알 수 있다.