ES6 - Prototype

marafo·2020년 9월 21일
0
post-thumbnail

✻ 개요

자바스크립트에서 특정 object의 prop 값을 읽으려고 할 때, 해당 프로퍼티가 없으면 숨겨져 있는 프로퍼티 값을 참조하게 된다. 이것을 프로토타입 상속이라고 한다. 보통 기존 객체와 유사하거나 약간의 차이가 있는 다른 객체를 만들 때 사용된다.

let animal = {
  eats: true,
};

let rabbit = {
  jumps: true,
};

rabbit.__proto__ = animal;
alert(rabbit.eats); // true
alert(rbbit.jumps); //true

rabbit 객체에는 eats 프로퍼티가 없지만 프로토타입을 통해 상속받는다. 여기서 eat는 상속 프로퍼티(inherited property)이다.

✻ 프로토타입 메서드

let animal = {
  eats: true,
  walk(){
    alert('동물이 걷고 있다');
  }
};

let rabbit = {
  jumps: true,
  __proto__: animal
};

rabbit.walk(); // 동물이 걷고 있다.

rabbit이 프로토타입 객체인 animal로 부터 walk()라는 메서드를 상속 받았다.

✻ 프로토타입 확장

let animal = {
  eats: true,
  walk(){
    alert("동물이 걷고 있다");
  }
};

let rabbit = {
  jumps: true,
  __proto__: animal,
};

let longEar = {
  earLength: 10,
  __proto__: rabbit,
};

longEar.walk(); // 동물이 걷고 있다.
alert(longEar.jumps); //true
         

프로토타입의 층이 깊어지고 복잡해질 때, 순환 참조는 불가능하다. 원형으로 닫힌 프로토타입 구조에서
프로토타입 객체를 참조하면 에러가 생긴다. 또한 프로토타입은 객체, null 이외엔 참조가 불가능하다.
그리고 하나의 프로토타입 객체만 상속 받을 수 있고 두 개 이상은 불가능하다.

✻ 프로토타입 읽기, 추가, 수정

let animal = {
  eats: true,
  walk(){
    //empty
  }
};

let rabbit = {
  __proto__: animal,
};

rabbit.walk = function(){
  alert("토끼가 뛰고 있다");
};

rabbit.walk(); // 토끼가 뛰고 있다.

rabbit.walk()가 작동하는 것은 animal 객체의 walk 메서드가 아니라 rabbit자체에서 추가한 메서드가 실행된 것이다. 프로토타입 객체에 없는 프로퍼티를 추가하거나 지우는 것은 rabbit에서 직접해야 한다.

let user = {
  name: "John",
  surname: "Smith",
  
  set fullName(value){
    [this.name, this.surname] = value.split(" ");
  },
  
  get fullName(){
    return `${this.name} ${this.surname}`;
  }
};

let admin = {
  __proto__: user,
  isAdmin: true
};

alert(admin.fullName); // John Smith

admin.fullName = "Alice Cooper";

프로토타입의 객체에 getter, setter 함수로 메서드가 정의될 때 다음과 같다.
alert문에서 fullName은 user객체 안의 getter함수 get fullName()을, 마지막 admin.fullName에선 setter함수 set fullName(value)을 호출한 것이다.

참고
1) https://ko.javascript.info/prototype-inheritance

profile
프론트 개발자 준비

0개의 댓글