프로토타입 객체와 __ proto __

자바스크립트는 애초에 객체지향을 바라보고 개발된 언어가 아니기 때문에 C++나 Java의 class 키워드가 존재하지 않았다. 자바스크립트에는 클래스라는 개념 자체가 없었다는 말인데, 그 대신 프로토타입 기반 언어라는 특성을 이용하여 객체지향의 기능을 구현하려는 많은 노력이 있어왔다.

프로토타입은 인스턴스를 만들 때 상속해줘야하는 속성과 메소드들을 가지고있는 객체로, 인스턴스가 상속받는 모델 객체라고 할 수 있다. 프로토타입 객체는 클래스를 만들 때 함께 생성되는데, 예를들어 function Person(){}을 통해 클래스를 선언해주면 그 안에는 아래 그림처럼 Prototype이라는 객체가 따로 생성이 된다.

__ proto __ 는 해당 클래스 혹은 인스턴스가 상속받고있는 클래스의 프로토타입 객체(부모 클래스)의 참조값을 가지고 있는 속성이다. C언어에서 포인터의 역할을 하고 있다고 생각하면 될 것 같다. 아래의 그림으로 설명하자면, 인스턴스 kim 은 Person 이라는 클래스를 상속받고 있기 때문에 kim.__ proto __ === Person의 프로토타입 객체가 될 것이다.
prototype.png

종합하자면, 자바스크립트는 객체지향 언어가 가지고 있는 클래스의 기능을 프로토타입 객체와 __ proto __ 를 이용하여 구현한다. 그렇다면, 글 자바스크립트에서의 클래스 구현에서 다룬 4가지 클래스 구현 방법 중 Psuedo classical 코드를 통해 상속 과정을 설명해보겠다.

Object.create()를 이용한 클래스 상속

아래는 Psuedo classical한 방법으로 상속, 다형성 까지 구현한 코드다. 상속을 구현할 때 반드시 해줘야할 작업은 자식 클래스의 프로토타입 설정생성자 연결이다.

프로토타입 설정

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

Object.create(Human.prototype)은 Human.prototype을 프로토타입으로 하는 객체를 반환한다. 여기서는 Student 클래스가 Human 클래스를 상속받게 하기 위해 Student.prototype에 할당했다.

생성자 연결

Student.prototype.consturctor = Student;

생성자(constructor function)는 프로토타입 객체 안에 있는 프로퍼티로, 객체의 입장에서 자신을 생성한 객체를 가리킨다. 클래스 입장에서는 객체를 생성하고 초기화하기 위한 특별한 메서드이다. 객체가 생성될 때 무조건 먼저 실행된다고 생각하자. 상속을 구현할 때 프로토타입만 설정하면 정작 Student 클래스와 Student의 constructor의 연결이 끊기기 때문에 따로 설정해줘야 한다.

var Human = function(name){
    this.name = name;
}
Human.prototype.sleep = function(){
  console.log(this.name + ' is sleeping!');
};
var steve = new Human('steve');
var Student = function(name){
      // 실행 컨텍스트에 따른 this를 전달해주기 위한 설정
    Human.call(this,name); // Human.apply(this,arguments);
}
////////////////////상속의 완벽한 구현////////////////
Student.prototype = Object.create(Human.prototype);    // 1. 프로토타입 설정
Student.prototype.consturctor = Student;               // 2. 생성자 연결
Student.prototype.learn = function(){
  console.log(this.name + ' is studying.');
};            
Student.prototype.sleep = function(){
  Human.prototype.sleep.apply(this);                    //3. 다형성 구현
  console.log('students never sleep');
}
//프로토타입을 설정해주고, constructor까지 설정해줘야한다///

// john <- Student <- Human
var john = new Student('john');
john.learn();
// john is studying
john.sleep();
// john is sleeping
// students never sleep

ES6 class keyword를 사용한 클래스 상속

ES6 자바스크립트에는 class 키워드가 추가됐다. Object.create()를 이용한 프로로타입 설정과 생성자 함수 설정을 class 키워드 하나로 해결할 수 있게 된 것이다. 클래스의 기본 구조는 다음과 같다. 한가지 설명하자면, constructor 함수 안의 super()는 부모 클래스의 constructor를 실행하는 역할을 한다. super()는 매우 유용해서, 메서드 안에서도 사용이 가능하다.

class parents{
  constructor(lastName){
    this.lastName = lastName;
  }
}
class child extends parents{
  constructor(lastName){
    super(lastName);
  }
  method(){
  }
}
class Human {
    constructor(name){
        this.name = name;
    }
    sleep(){
        console.log(this.name+' is sleeping.');
    }
}

class Student extends Human{
    //부모의 생성자와 모양이 같다면 생성자를 생략할 수도 있다
    constructor(name){
        super(name);
    }
    learn(){
        console.log(this.name+' is studying.');
    }
      // 다형성
    sleep(){
        super.sleep();    // Human 클래스의 sleep 호출
        console.log('students never sleep!!');
    }
}

var john = new Student('john');
john.learn(); // john is studying
john.sleep(); // students never sleep!!