자바스크립트에서의 상속이란?

박상록(Sangrok Park)·2020년 10월 28일
0

TIL(긴 글)

목록 보기
4/12

상속이란?

상위객체의 특징을 하위객체에게 넘겨주는 것. 자식 객체는 부모 객체를 base로 하여 새로운 기능을 추가한다.

Pseudoclassic 상속(고전적인 방법의)

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

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

const steve = new Human('Steve');

Human => Human.prototype.sleep => Steve.sleep 순으로 상속이 이루어짐.

prototype: 청사진. Original Form.
constructor: 인스턴스가 초기화 될 때 실행하는 생성자 함수
this: 함수가 실행될 때, 해당 scope마다 생성되는 고유한 실행 context(execution context.) new 키워드로 인스턴스를 생성했을 때에는, 해당 인스턴스가 바로 this의 값이 됨.

instantiation: 인스턴스를 생성하는 것.

우리가 쓰는 자바스크립트 빌트인 method들도 다 상속이라는 것

Array method를 MDN에서 봤을 때, Array.prototype.filter(), Array.prototype.concat() 이렇게 써있는 것도, Array원형의 속성을 상속받기 때문.

Array 생성시, let arr = [];과 더불어, let arr = new Array()라고 생성하게 되도 결과는 똑같다.

하지만 airbnb coding convention에 따르면, 객체를 생성할 때, 그냥 직접적으로 let arr = [];와 같은 방식으로 생성하라고 명시해 뒀기에 그것을 따라보기로 한다.

Steve와 prototype의 관계

그럼 왜 여기서, steve는 Human prototype으로 설정 해놓지도 않은 toString Method를 사용할 수 있었을까?

이유는 바로 => 모든 객체는 객체의 가장 상단 Object로부터 상속받기 때문.

결국 위로 따라가다보면, Object()를 만나게 된다.

하나의 객체로부터 상속을 받고, 다른 곳에도 Assign하는 법

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

Human.prototype.sleep = function () {
  console.log('zzz');
}

function Student () {
  
}

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

let student1 = new Student();

Student.prototype.learn = function() {console.log('learning...')}

student1.learn();
student1.sleep();

Object.create() 이 method를 이용해서 하는 방법이 있지만,
기존 constructor를 새로 prototype 연결되는 객체의 constructor로 대체시켜서 그리 좋은 방법은 아니다.

실행장면

원래 대로라면 위와 같이 constructor는 Student가 되야하지만,

이렇게 Human의 속성을 상속 받았다고 해서 constructor까지 Human으로 바뀌어지면, 나중에 혼란을 줄 것 같다.

그래서 Pseudoclassic한 방법으로 상속을 정확히 구현하려면,
위와같이 상속을 해주고, 꼭 Student.prototype.constructor = Student라고 재 할당 해주어야 한다.

추가: 상속을 받는 Student 함수 안에 Human.call(this)라고 꼭 써줘야 한다.
그래야만 새로운 인스턴스를 생성할 때 마다 실행 컨텍스트를 받아와 this값을 잘 사용할 수 있기 때문.

근데 뭔가 불편하다..

그래서 탄생한 키워드 Class

원래 객체지향을 목표로 두고 만들어진 자바스크립트가 아니였기 때문에 class라는 문법적 선택을 들여오지 않았었던 것 같은데, 자바스크립트에 OOP적인 방법론들이 추가가 되면서, 위와 같은 고전적 상속의 방법을 지나 이렇게 Class개념을 적극적으로 도입한게 아닌가 싶다. 왜냐면 너무 쓰기 쉬우니까.

앞으로는 점점.. 언어의 경계가 허물어지는게 아닌가 싶기도 하고.

어쨌든, 위와 같은 문법적 원리를 Class라는 키워드를 통해 간단히 해결 할 수 있다.

class Human {
  constructor(name) {
    this.name = name;
  }
  sleep() {
    console.log('zzz')
  }
}

const steve = new Human('steve');

class Student extends Human {
  learn() {
    console.log('learning...')
  }
}

const student1 = new Studnet('student1')

출력되는 결과는 Pseudoclassic하게 작성된 것과 똑같다.
즉 작성된 문법은 달라졌지만, 내부 작동구조는 똑같다는 이야기이다.
하지만 여기서도 토론해볼 주제가 하나 있는데.
내부적으로는 결국 고전적 방법과 동일하게 작동하지만, 우리가 쓰는 문법자체가 달라졌기에 혹자는 "이것은 Syntatic Sugar에 불과하다", 또 다른 분들은 "아니다, 내부적으로도 서로 다르다."하는 상반된 글들을 봤는데, 이 부분은 더 공부를 해봐야 할 부분인 것 같다.

결론

Class는 자바스크립트에서의 상속이라는 개념을 정말 편하게 만들어줬다!

profile
한 줌의 소금과 같이 되고 싶은 개발자

0개의 댓글