[TIL] 프로토타입 체인

송인선·2022년 7월 25일
0

TIL

목록 보기
8/16
post-thumbnail

Today I Learn...

지난 글에서 썼던 프로토타입 체인을 조금 더 자세히 알아보자!

프로토타입 체인이란?


상속을 JavaScript에서 구현할 때는 프로토타입 체인을 사용한다!
상속한다 = 객체와 객체를 연결 해 멤버 함수나 멤버 변수를 공유한다

일단 염두에 둘 것은, 모든 객체의 최상위 타입은 ⭐️Object⭐️라는 것이다.
체인을 타고 올라 올라가다보면 결국은 Object를 맞닥뜨리게 된다.

📌 DOM과 프로토타입

  • JavaScript는 프로토타입 기반 언어이며, DOM도 프로토타입으로 상속을 구현

  • document.creatElement('div')를 이용하면 새로운 div 엘리먼트를 만들수 있다.
    이때 이 div 엘리먼트는 HTMLDivElement라는 클래스의 인스턴스이다.
    아래 실습 문제를 풀어보면 해당 엘리먼트의 프로토타입 체인을 확인 할 수 있다.

let div = document.createElement('div');

div.__proto__ 
div.__proto__.__proto__
div.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__

콘솔창으로 확인해보자!

  • div가 addEventListener 메서드를 사용할 수 있는 이유는 EventTarget 을 상속하고 있기 때문

    • EventTarget.prototype에 addEventListener 메서드가 존재
    • div는 HTMLDivElement의 인스턴스이고 EventTarget을 상속받았기 때문에 addEventListener를 사용할 수 있다~
  • 보통 클래스의 인스턴스는 new 키워드로 생성하지만, DOM에서는 new 키워드가 아닌 createElement를 사용

extends 와 super


먼저 Person이라는 class를 만들어주자.

class Person {
  constructor(first, last, age, gender, interests) {
    this.name = {
      first,
      last
    };
    this.age = age;
    this.gender = gender;
    this.interests = interests;
  }

  greeting() {
    console.log(`Hi! I'm ${this.name.first}`);
  };

  farewell() {
    console.log(`${this.name.first} has left the building. Bye for now!`);
  };
}

📌 하위 클래스 생성 --> extends키워드로 상속받을 클래스를 명시
extends를 사용해서 Person의 멤버를 Teacher에게 상속한다.

class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    this.name = {
      first,
      last
    };

  this.age = age;
  this.gender = gender;
  this.interests = interests;
  // subject and grade are specific to Teacher
  this.subject = subject;
  this.grade = grade;
  }
}

📌 상위 클래스 생성자 호출 --> super()연산자의 매개변수를 통해 멤버 상속
❗️ 파생 클래스에서 super() 함수가 먼저 호출되어야 this 키워드를 사용할 수 있다. 그렇지 않을 경우 참조오류가 발생!
❗️ 생성자 함수 내의 super 키워드는 한번만 사용 가능

class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);

    // subject and grade are specific to Teacher
    this.subject = subject;
    this.grade = grade;
  }
}

📌 Teacher의 인스턴스를 생성하면 Teacher와 Person 양쪽의 메서드를 사용할 수 있다

let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
snape.greeting(); // Hi! I'm Severus.
snape.farewell(); // Severus has left the building. Bye for now.
snape.age // 58
snape.subject; // Dark arts

Getters와 Setters


📌 생성한 클래스의 인스턴스의 속성 값을 변경하거나 최종 값을 예측할 수 없는 경우
--> 이런 상황에 getter / setter 가 필요!

  • getter와 setter는 쌍으로 동작하며, getter가 현재 값을 반환 한다면 그에 대응하는 setter는 해당하는 값을 변경한다. 👯‍♀️
class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);
    // subject and grade are specific to Teacher
    this._subject = subject;
    this.grade = grade;
  }

  get subject() {
    return this._subject;
  }

  set subject(newSubject) {
    this._subject = newSubject;
  }
}
  • subject 속성에 대해 getter와 setter가 생겼다.
    멤버 변수에는 _를 붙여 getter/setter와 구분
    (이렇게 하지 않으면 get/set을 호출할때마다 에러가 발생한다)

  • snape 객체의 _subject 속성 값을 보려면 snape._subject를 실행

  • _subject에 새 값을 할당하려면 snape._subject="new value"를 실행

[참고]

ECMAScript 2015 클래스
쉽게 이해하는 자바스크립트 프로토타입 체인

profile
캣닙같은 마성의 개발자

0개의 댓글