[TIL] Prototype Chain & Class (ES6)

woojun kang·2020년 9월 12일
0

proto, constructor, prototype 이 각각 어떤 관계를 가지고 있는지 조사해봅니다.
Object.create 메소드에 대해 이해합시다.
ES6 class 키워드 및 super 키워드 이용 방법을 알아봅니다.

Subclassing - prototype chain


JavaScript는 원래 객체지향을 염두에 두고 만들어진 언어가 아니다. prototype 기반 언어이다. javascript에서 어떻게 객체지향 방법론을 구현할지... 프로토타입은 원형객체(original form)이다. 즉 복제품을 만들기위한 설계도인 셈이다. 클래스 생성 시 prototype이 생성된다.

function Car(brand, name, color) {
  this.brand = brand; 
  this.name = name;
  this.color = color;
} // ES6 클래스에서 constructor(생성자)의 역할 -> instance 초기화시 실행...
Car.prototype.dirve = function() {
  console.log(this.name + '가 운전을 시작합니다');
}
let avante = new Car('hyundai', 'avante', 'black'); // this가 avante가됨.
avante.color; // black
avante.dirve(); // avante가 운전을 시작합니다.
  • this: 함수 scope마다 생성되는 고유한 실행 context(excution context). 인스턴스 생성 시 해당 인스턴스가 this가 됨.
  • prototype: 프로토타입은 할당이 가능하다. 따라서, 프로토타입안에 자신이 만든 메소드를 할당할 수 있다.

Object.create();

: 인자로 들어온 프로토타입을 바탕으로 프로토타입 복사본을 만든다. 이 메소드를 사용하는 이유는 2개의 프로토타입이 있을 때, 하나의 프로토타입이 다른 하나의 프로토타입을 참조하고 싶을때 사용된다. Object.create() 메소드를 활용하면 참조된 프로토타입에 영향없이 참조받은 프로토타입에 새로운 메소드 추가가 가능하다. Object.create() 메소드 없이 하나의 프로토타입에 다른하나의 프로토타입을 바로 참조하게 되면 서로 영향을 끼치게된다.

  • O: a.prototype = Object.create(b.prototype)
  • X: a.prototype = b.prototype

function Human(name) {
  this.name = name;
};

function Student(){
};

Student.prototype = Object.create(Human.prototype);
// 정확한 prototype chain 구현을 위해 prototype의 constructor를 다시 Student로 바꿔주는 작업을 해야함 (javascript는 애초에 OOP 고려하지 않고 만들어져서..)
Student.prototype.constructor = Student; 
Student.prototype.learn = function(){console.log('learning...')};
Human.prototype.sleep = function(){console.log('zzz')};
Human.prototype // 여기에는 learn 메소드 없음. but Student에서 sleep메소드 사용가능

let student1 = new Student();
student1.learn() // learning...
student1.sleep() // zzz

여기서 Student의 this가 Human까지 가지 않는다. 따라서 Human까지 this를 전달해주기 위해 아래와 같이 call method를 사용해야 한다.

function Student(){
  Human.call(this, name);
};

Class (ES6)


: 위에서 본 prototype chain을 쉽게 구현하기 위해 ES6에서 class 키워드가 등장했다. 이후 위에 방법은 legacy가 돼버렸다.

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

var woojun = new Human('woojun');

class Student extends Human {
	/* 생략가능 */
  constructor(name) {
    super(name); // Human의 속성과 메소드를 호출할 때 사용됨.
  }
 	/* 여기까지 */
  learn() {
  }
  // sleep() 메소드 재정의 가능
}
var john = new Student('john');
john.learn();
john.sleep();
  • 자식 클래서에서 부모 클래스어 속성이 같은 경우 constructors는 생략이 가능하다.

0개의 댓글