Inheritance and Prototype

suyeonme·2021년 1월 16일
1

Interview prep

목록 보기
21/22
post-thumbnail

class 기반의 패러다임을 가진 다른 OOP언어들과 다르게, 자바스크립트는 prototype 기반의 언어이며 prototypical inheritance라고도 불립니다.

Prototype

모든 오브젝트는 숨겨진 내부 프로퍼티(inner property)인 [[Prototype]]을 가지고 있습니다. 각 오브젝트는 그들의 constructor의 [[Prototype]] 부터 프로퍼티와 메소드를 상속받을 수 있습니다.

  • [[...]]는 내부 프로퍼티를 의미하며 바로 접근할 수 없음
  • getPrototypeOf() 혹은 .__proto__를 사용해서 [[Prototype]]에 접근
Object.getPrototypeOf(x); // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, …}
x.__proto__; // legacy

Prototype Inheritance

오브젝트의 프로퍼티 혹은 메소드에 접근할 때, 자바스크립트는 먼저 오브젝트에서 찾습니다. 만약 발견되지 않는다면 오브젝트의 [[Prototype]]로부터 찾게 됩니다. 그 이후에도 찾아지지 않는다면 linked object의 prototype을 찾게 되고 이런식으로 쭉 올라가게 됩니다. 이러한 과정을 prototype chain이라고 합니다. 모든 prototype chain의 끝은 Object.prototype 입니다.

예를들면,
1️⃣ const obj = {};

  • Object.prototype으로부터 모든 프로퍼티를 상속받음
  • prototype chain: obj -> Object

2️⃣ const arr = [];

  • Array.prototype으로부터 모든 프로퍼티를 상속받음
  • prototype chain: y -> Array -> Object

Constructor Functions

Constructor functions은 새로운 오브젝트를 만들 수 있는 함수입니다.
constructor function에 기반한 새로운 인스탄스를 만들기 위해 new 키워드와 함께 사용합니다.

  • built-in constructor로 new Array(), new Date()등이 있음

(예제1)

// Initialize a constructor function
function Hero(name, level) {
  this.name = name;
  this.level = level;
}

Hero.prototype.greet = function () {
  return `${this.name} says hello.`;
}

let hero1 = new Hero('Bjorn', 1); // [[Prototype]]: Hero
hero1.greet(); // Bjorn says hello.

(예제2) Sub Constructor 생성

  • call()을 사용해서 constructor에 chaining할 때, Prototype properties와 메소드는 자동적으로 연결이 되지 않는다. 따라서 Object.create()를 사용해서 Constructor의 프로퍼티와 메소드를 상속받을 수 있도록 연결해줘야 한다.
// Super Constructor
function Hero(name, level) {
  this.name = name;
  this.level = level;
}

// Sub Constructors
function Warrior(name, level, weapon) {
  Hero.call(this, name, level);
  this.weapon = weapon;
}

function Healer(name, level, spell) {
  Hero.call(this, name, level);
  this.spell = spell;
}

// Link prototypes and add prototype methods
Warrior.prototype = Object.create(Hero.prototype);
Healer.prototype = Object.create(Hero.prototype);

Hero.prototype.greet = function () {
  return `${this.name} says hello.`;
}

Warrior.prototype.attack = function () {
  return `${this.name} attacks with the ${this.weapon}.`;
}

Healer.prototype.heal = function () {
  return `${this.name} casts ${this.spell}.`;
}

// Initialize individual character instances
const hero1 = new Warrior('Bjorn', 1, 'axe');
const hero2 = new Healer('Kanin', 1, 'cure');
hero1.greet(); // Bjorn says hello
profile
Frontend Engineer.

0개의 댓글