Prototype Chain

안정태·2021년 4월 9일
0

Study

목록 보기
4/33

javascript는 모든 객체의 속성과 메소드를 상속 받기 위해서 prototype을 사용합니다. 이렇게 상속 받은 객체는 또 그 상위의 객체에서 상속을 받을 수 있습니다. 이렇게 상속에 상속을 받으면서 연결 되는 것을 'Prototype Chain' 이라고 합니다.

__proto__

__proto__는 생성된 인스턴스의 프로토타입을 조회하는데 사용된다.

const Human = function(name){
  this.name = name;
} //Human을 생성하는 클래스

Human.prototype.study = function() { console.log("공부 중...")};
//Human 프로토타입에 study메소드 추가

const student = new Human('Ancoding');
//안코딩이라는 이름의 학생 생성

위 코드를 통해서 클래스와 인스턴스를 정의해 주었다. 여기서 생성된 인스턴스의 프로토타입과 휴먼의 프로토타입은 같을 것이다. 하지만 그걸 조회 하는 방법이 조금 다른데

인스턴스의 프로토타입 조회 : 인스턴스명.__proto__
클래스의 프로토타입 조회 : 클래스명.prototype

위와 같은 형식으로 설명한다면

student.__proto__ === Human.prototype //true

가 성립하게 된다. 단, 여기서 주의 해야 할 점은 만약 클래스 안에 있는 prototype을 수정하고 싶으면 .prototype만을 사용해서 수정해야 한다. __proto__는 조회의 용도로만 사용해야 한다.

constructor

constructor은 클래스 내에서 객체를 생성하고 인자를 받아 그 인자로 객체의 키와 키값을 초기화 하는 메소드이다.

class Car {
    constructor(name, number){
        this.name = name;
        this.number = number;
    }
}// Car클래스 정의 : constructor 메소드가 사용되어 있다.

let audi = new Car('A5',1234); //Audi라는 인스턴스 생성

위와 같이 코드를 입력 한다면 과연 Audi에 들어가 있는 값은 무엇 일까?
앞서 설명한 constructor에 의해서 Audi는 객체로 생성된다.

typeof audi === 'object'; //true

prototype

완벽하게 이거다! 할 수는 없겠지만 내가 받아들이기에 메소드들의 저장소 라고 이해하고 있다. 앞서 말한 상속을 위해서 prototype안에 여러가지 메소드를 정의해두고 이 메소드들을 자식 클래스들에게 상속해주기 위해 사용한다.

//prototype을 이용한 상속
//Human이라는 부모 클래스와 Student라는 자식 클래스가 있다고 가정한다.

Student.prototype = Object.create(Human.prototype);
//Student.prototype에 Human.prototype을 추가로 만들어준다.
//But, 이렇게 해버리면 Student의 constructor또한 Human의 것으로 바뀌어 버린다.

Student.prototype.constructor = Student;
//Student의 constructor를 다시 Student의 것으로 바꿔준다.

솔직히 이렇게 보면 '상속 = 자식 메소드에 부모 메소드 복사 붙여넣기'로 생각된다. 여기서 메소드들을 담고 있는 것이 prototype이라고 생각된다. 상속을 할 때 마다 항상 이 코드들을 타이핑 하면 그 만큼 에너지 소비가 없기 때문에 향후 class의 등장으로 상속이 조금 더 편해졌다.

Class

javascript의 OOP를 더욱 수월하게 하기 위해 ES6부터 생겨난 고마운 친구다.

//ES5의 클래스 정의
function Car('name','number'){
  this.name = name;
  this.number = number;
  
  Car.prototype.drive = function(){};
}

//ES6의 클래스 정의
class Car {
  constructor('name','number'){
    this.name = name;
    this.number = number;
  }
  
  drive(){};
}

위 코드를 통해 본다면 ES5는 뭔가 클래스 보다는 함수에 가깝다는 느낌이다. 메서드를 정의 하는 방식 또한 훨씬 간결해지고 쉬워졌다는 걸 알 수 있다.

super

앞서 prototype을 이용한 상속 방식을 보여줬다. 하지만 이 방식은 코드의 길이가 너무 길어지고 복잡해질 우려가 있다. 그런 불편함을 한번에 해소해줄 친구가 바로 super메소드다. super은 부모의 메서드를 호출할 때 사용된다.

class Parent {
    constructor(name){
        this.name = name;
    }
    parentFunction(){console.log('부모함수')};
} //먼저 부모 클래스를 하나 정의 해준다.

class Child extends Parent { //extends를 통해 상속 받을 부모를 정의해준다.
    constructor(childName){
        super(childName);//부모의 생성자 함수(constructor)를 가져와 쓴다.
      	//생성자 함수의 경우 그냥 super만 사용하면 된다.
    }
    useParentFunction() {
        super.parentFunction();//부모 함수 가져오기
    }
} //아이 클래스 생성

위 코드를 보면 super의 사용법을 확실히 익힐 수 있다. 원리는 prototype과 같지만 훨씬 간단하게 부모의 속성과 메소드를 상속 받을 수 있다.

profile
코딩하는 펭귄

0개의 댓글