Inheritance Patterns

Verba volant, scripta manent·2021년 1월 14일

프로토타입과 상속

프로토타입(Prototype)이란?

자바스크립트의 모든 객체는 최소한 하나 이상의 다른 객체로부터 상속을 받는데, 이때 상속되는 정보를 제공하는 객체를 칭한다.

__proto__, constructor, prototype의 관계

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

Human.prototype.sleep = function() {};

var steve = new Human('steve');

라고 할 때

prototype : 모든 function에는 prototype 이라는 속성이 있다. assign이 가능함
constructor : 일명 생성자. 특정 객체가 생성될때 실행되는 코드
instantiation : 인스턴스를 생성하는 과정
__proto__ : [[Prototype]] , 프로토타입 체인이라고 불림.

예제의 코드를 개발자 콘솔 실행시킨 결과이다.

var Array = function(location) {
  [native code] // 브라우저 안에서 지원되는 코드 
}

Array.prototype.push = function() {};
Array.prototype.slice = function() {};
...

var arr = new Array();

Array도 마찬가지이다.

프로토타입 체인(prototype chain , __proto__)

객체의 입장에서 봤을때 자신의 부모 역할을 하는 프로토타입 객체

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

Human.prototype.sleep = function() {};

var steve = new Human('steve');
steve.toString(); //[object Object]


그러면 왜 steve.toString();[object Object]가 될까?

상속의 최상위 단계에 object가 있기 때문이다.

Object.create()

Object.create()란?

지정된 프로토타입 객체 및 속성을 갖는 새 객체를 만드는 것

첫 번째 인수 : 프로토타입으로 사용할 객체를 전달
두 번째 인수 : 새로운 객체의 추가할 속성 정보를 전달

ex)

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;

가 된다.

대충 관계도는 이렇다.

여기서 Student.prototype.learn에서 Human.prototype.sleep을 사용하려면 어떻게 해야될까?

① john.proto__ = Human.prototype => 안됨(참조하는 용도로만 써라)

② Student.prototype.learn에 Human.prototype.sleep을 대입 => 안됨(learn이 실행안됨, 객체참조가 바뀌게된다)

사실상 Human.prototype.learn과 같게된다.

③ prototype of을 이용(Human.prototype.sleep을 카피한 것을 Student.prototype.learn에 넣으면?) => 여기서 prototype of는 Object.create(proto)가 된다.

③번 방법처럼 실행해보자.

여기까지 한 뒤 student1 instanceof Student, student1 instanceof Human를 실행하보면 true가 나온다.

그러나 student1.__proto__를 실행하게 되면 sleep에 대한 부분은 명확히 나오지 않는다.

그 이유는 constructor가 연결이 잘 안됬기 때문이다.
따라서 Student.prototype.constructor = Student;를 추가해줘서 상속을 명확히 설정해줘야했다.

그리고 또 해줘야 하는 부분이 있다.

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

Human.prototype.sleep = function() {};

var steve = new Human('steve');

var Student = function(name) {
  Human.call(this, name); // 요부분 추가 
}

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

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

위의 코드를 개발자 콘솔에 입력해서 john을 실행하면

이렇게 나온다.

class/super

class

class는 객체를 생성하기 위한 템플릿이다.

super

super는 부모 객체의 함수를 호출할 때 사용된다.

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

Human.prototype.sleep = function() {};

var steve = new Human('steve');

var Student = function(name) {
  Human.call(this, name); // 요부분 추가 
}

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

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

위의 복잡한 코드를 classsuper를 이용해서 고치면

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

var steve = new Human('steve');

class Student extends Human {
  constructor(name) {
    super(name);
  }
  learn() {
  }
}
var john = new Student('john');
john.learn();
john.sleep();

원리만 똑같을뿐 이렇게 된다. class Student extends Human에서 thissuper로 대체한다.

classsuper를 이용해서 고친 코드를 개발자 콘솔에 입력 후 john을 실행해보면

이런 결과가 나온다.

profile
말은 사라지지만 기록은 남는다

0개의 댓글