3. Inheritance Patterns - Prototype Chain

xlsoh·2020년 9월 9일
0

TIL

목록 보기
11/23
post-thumbnail

Before You Learn

new 키워드를 이용한 인스턴스 생성시 사용하는 this 키워드에 대한 이해

function Car (brand,name,color) {  //Car : class
  this.brand = brand;              //this 객체
  this.name = name;
  this.color = color;
}                                  // function {} : constructor(생성자) 함수

Car.Prototype.drive = function() { // Prototype 객체 (속성이나 메서드 정의 가능)
  console.log (this.name + "운전 중");
}

let Avante = new Car ('hyundai','avante','black');  // Avante : instance
avante.color;
avante.drvie();
분류
Prototype원형 객체 (original form)
Constructor인스턴스가 초기화 될 때 실행되는 생성자 함수
this함수가 실행 될 때, 해당 scope마다 생성되는 고유한 실행 context (execution context)

Prototype Chain

  • [[Prototype]] __proto__

eg) Array.prototype (.push .slice .map... native code) -> arr에 사용

arr.__proto__ === Array.prototype   //true
function Human (name) {
  this.name = name;
}
Human.prototype.sleep = function () {};
let steve = new Human ('steve');

steve.__proto__  === Human.prototype   //true  -> 'steve'의 부모 prototype 프로퍼티에 대한 정보 참조한 값 : Human.prototype

steve.toString();   // '[Object Object]'  -> prototype chain 최 상단 : Object

Prototype Property

  • __proto__
    • 모든 객체가 가지고 있는 속성
    • 부모의 prototype 프로퍼티에 대한 정보 참조
  • prototype
    • 함수 객체만이 가지는 프로토타입
    • 자신의 prototype 객체
    • 할당 가능
var MyArray = function () {}
MyArray.prototype = Array.prototype;
var myarr = new MyArray();
myarr.push(1)     // MyArray[1]  -> assignable prototype (할당 가능)

상속(inheritance) 구현

To-do가 될 수 있도록 하려면?

var Human = function (name) {
  this.name = name;
}
Human.prototype.sleep = function () {};
var steve = new Human('steve');

var Student = function (name) {}
Student.prototype.learn = function () {};
var john = new Student('john');
john.learn();
john.sleep();

steve instanceof Human === true;
john instanceof Student === true;
john instanceof Human === true;   //To-do

Pseudoclassical

시도 1)

john.__proto__ = human.prototype  //(X) DEPRECATED 

--> __proto__는 참조 용도로만 쓰도록 권장됩니다.

시도 2)

Student.prototype = Human.prototype //(X) 

--> Human.prototype.learn 이 생겨버립니다.

시도 3)

Student.prototype = Object.create(Human.prototype)

--> Object.create() 메서드를 사용하세요. 참고 reference

--> To-do는 이루어 졌지만, constructor의 관계가 제대로 연결되지 않았습니다.

john.__proto__.constructor // Human (Student가 나와야 제대로 연결된 것) 

시도 4)

Student.prototype = Object.create(Human.prototype);
Student.prototype.constructor = Student;
Student.prototype.learn = function () {};

--> new 키워드를 써서 constructor 하면 context가 전달이 되지 않습니다.
new 키워드를 쓰면 인스턴스가 this가 되는데, 그 인스턴스가 Human까지 올라가지 않습니다. (Human의 this가 undefined)

Final)

var Human = function (name) {
  this.name = name;
}
Human.prototype.sleep = function () {};
var steve = new Human('steve');

var Student = function (name) {
     Human.call(this,name);  // Human.apply(this,arguments)  do
}
Student.prototype = Object.create(Human.prototype);   // do
Student.prototype.constructor = Student;   // do
Student.prototype.learn = function () {};
Student.prototype.sleep = function () {
Student.prototype.sleep.bind(this);  // Human.prototype.sleep에 추가 하고 싶다면 이 줄 가능
//왜 apply(Maximum call stack size exceeded) 아닌 bind?
console.log ();
}

var john = new Student('john');
john.learn();
john.sleep();

Using Class Keyword

ES6 문법에서 새롭게 적용된 classextends,super 키워드를 이용하여, 위의 pseudoclassical 방식에서 복잡하게 구현했던 내용을 간단하고 명료하게 구현할 수 있습니다.

class Human {
constructor(name) {
  this.name = name;
}
  sleep () {
  }
}
var steve = new Human('steve');
class Student extends Human {
  constructor(name) {      // 자식 constructor부분 생략가능 (부모-자식 constructor 아규먼트 같음)
    super(name);
  }
  learn () {
  }
}
var john = new Student('john');
john.learn();
john.sleep();
profile
주니어 프론트엔드 개발자

0개의 댓글