[javascript] 프로토타입

Yuni·2022년 7월 22일
0

코드스테이츠

목록 보기
19/39

프로토타입 상속

프로토타입이란 원형 객체를 의미하고 자바스크립트는 프로토타입 기반의 언어이다.

🤔 프로토타입 기반언어?
자바스크립트의 모든 객체들이 메소드와 속성들을 상속 받기 위해 프로토타입 객체를 가진다. 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지이다. 이를 프로토타입 체인(prototype chain)이라 부르며 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 하는 근간이다.

[[Prototype]]

위에서 말한 프로토타입 객체는 객체의 [[Prototype]]이라는 속성에서 확인할 수 있다. 속성 값은 null이거나 다른 객체에 대한 참조가되는데 다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부른다.

class Human {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sleep() {
    console.log(`${this.name}은 잠에 들었습니다`);
  }
}

//생성자 함수를 이용해 객체를 생성한다.
let kimcoding = new Human('김코딩', 30);
let kimhacker = new Human('김해커', 18);

// 위에 생성한 2개의 인스턴스에 동시에 메서드를 상속하고 싶을 때 prototype 객체를 이용할 수 있다.
Human.prototype.tellName = function() {
	console.log('제 이름은 ' + this.name + '입니다.');
};

// 생성자 함수를 이용해 생성한 두 객체는 prototype 객체를 참조하기 때문에 tellName 메서드를 이용할 수 있다. 
// 이 특성을 이용해 자바스크립트는 prototype을 이용해 상속을 구현한다.
kimcoding.tellName();  //'제 이름은 김코딩입니다.'
kimhacker.tellName();  //'제 이름은 김해커입니다.'

// 객체의 constructor는 자신을 생성한 객체를 가리킨다.
Human.prototype.constructor === Human; // true
// 상속된 prototype 객체는 _proto_프로퍼티에 담긴다.
Human.prototype === kimcoding.__proto__; // true
Human.prototype.sleep === kimcoding.sleep; // true
  • 상속해준 속성과 메서드에 접근하려면 .prototype
  • 상속받은 속성과 메서드에 접근하려면 _ _proto__

Human의 생성자 함수로 만든 인스턴스 kimcoding을 console.log()로 출력해보면 kimcoding의 프로토타입 객체인 Human에 정의된 멤버들과 Human의 프로토타입인 Object에 정의된 다른 멤버도 볼 수 있다.

🤔 Object에 정의되어 있는 메소드를 kimcoding에서 호출하면 어떻게 될까?
kimcoding.valueOf()

  • 브라우저는 우선 kimcoding 객체가 valueOf() 메소드를 가지고 있는지 체크한다.
  • kimcoding에는 valueOf()가 없으므로 kimcoding의 프로토타입 객체(Human() 생성자의 프로토타입)에 valueOf() 메소드가 있는지 체크한다.
  • Human에도 없으므로 Human() 생성자의 프로토타입 객체의 프로토타입 객체(Object() 생성자의 프로토타입) valueOf() 메소드를 가지고 있는지 체크하고 호출한다.

class 상속

아래와 같이 Person을 class 문법으로 상속받아 Teacher 클래스를 만드는 것을 하위 클래스 생성이라 부른다.
하위 클래스를 만드려면 Javascript에서 extends 키워드를 통해 상속 받을 클래스를 명시해야한다.

// 상위 클래스
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!`);
  };
}

// 하위 클래스
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와 grade는 상속받지 않은 Teacher 클래스의 고유 멤버이다.
  this.subject = subject;
  this.grade = grade;
  }
}

아래 코드처럼 constructor()에서 첫번째로 super() 연산자를 정의하면 상위 클래스의 생성자를 호출하며 super()의 매개변수를 통해 상위 클래스의 멤버를 상속받을 수 있다.

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

    // subject와 grade는 상속받지 않은 Teacher 클래스의 고유 멤버이다.
    this.subject = subject;
    this.grade = grade;
  }
}

참고

Javascript info 프로토타입 상속

MDN Object prototypes

MDN Classes in JavaScript

MDN 상속과 프로토타입

profile
배운 것을 기억하기 위해 기록합니다 😎

0개의 댓글