Programming/Java Script

[JS] 프로토타입 : Prototype + Class 상속

감귤밭호지차 2023. 3. 15. 14:15

JS에서는 프로토타입 기반의 객체지향 언어입니다. 프로토타입 기반 객체지향 언어는 Class가 필요없는 객체지향 프로그래밍 언어어였습니다만, ES6에서 CLASS 기능이 출현했습니다. 

 

 

 

🔖 ES5에서 상속은 어떻게 구현 했을까? 

이전의 경우에는 ' 프로토타입'을 통해 <상속>을 구현했습니다. 

//ES5 생성자 함수 
var Person = (function () {
	//생성자 함수
	function Person(){
    	this.name = name;
    }
    
    //프로토타입 메서드
    Person.prototype.hello = function(){
    	console.log(`Hi I am ${this.name}`);
    };
    
    //생성자 함수 반환
    return Person;
}());

//인스턴스 생성
let emma = new Person("Emma");
emma.sayHi(); // Hi I am Emma.

 

 

 

 __ proto__  ] 는 Prototype 용 getter · setter 입니다. 최근에는 Object.getPrototypeOf  Objec.setPrototypeOf 을 써서 프로토타입을 획득하거나 설정한다고 합니다. 

[1] 하위 객체 .__proto__ = 상위 객체

[2] 하위 객체 = {
         하위 속성/메소드,
         __proto__ :  상위 객체
      };

 

이렇게 되면, 하위객체가 상위 객체의 속성/메소드를 사용할 수 있도록 프로토타입이 되도록 설정 된 것입니다. 또한, 아래와 같이 프로토타입은 읽기 전용 이니, 프로퍼티를 추가 / 변경 / 수정 은 객체에 직접 해야 합니다. 

 

 

 

 

 

 

🔖 ES6에서의 상속 : Class

 

가장 큰 CLASS 와 프로토타입의 차이는 다음과 같습니다. 

  1. CLASS를 new 연산자 없이 호출하면 ERROR
  2. 상속을 지원하는 extends 와 super 키워드
  3. CLASS는 호이스팅이 발생하지 않는 것 처럼 동작. : super 키워드 선언 이전에 this.속성 이 오면 ERROR
  4. CLASS 내의 모든 코드에는 암묵적으로 strict mode 지정 
  5. CLASS의 constructor/프로토타입 메서드/ 정적 메서드는 모두 프로퍼티 어트리뷰트의 값이 false.

 

 

CLASS 의 구성 요소에는 constructor(생성자), 프로토타입 메서드, 정적 메서드 3가지가 있습니다. 위의 ES5 문법과 비교하면 이해하기 더 쉬울 것 입니다.  참고로 constructor은 Class 내에 반드시 한 개만 존재해야 합니다. 

* super (상위 클래스 속성)으로 상위 클래스 속성할 때는 한번 만, 메서드를 참조할 때는 여러번 가능합니다. 

class Person {
	//생성자
    constructor(name){
    this.name = name;
    }
    
    //프로토타입 메서드
    hello(){
    	console.log(`Hi I am ${this.name}`);
    }
    
    //정적 메서드 
    static hello(){
    	console.log(`Hi I am ${this.name}`);
    }
    
    //인스턴스 생성 
    const emma = new Person('Emma');
    hello(me.name); // Hi I am Emma;
    
}

 

 

 

 

 

 

# 프로토타입과 클래스

배열과 DOM도 비슷한 구조입니다.

 

[  CLASS ]

*.constructor  ↑↓  * prototype 

[ CLASS.prototype.속성 / 메서드 ] 

    * .__proto__   ↑↓  * new Class(); 

[ 인스턴스.속성 / 메서드 ]

 

 

* [ .__proto__ ] 을 이용하면 부모 클래스의 프로토타입 , 부모의 부모 클래스의 프로토타입을 탐색할 수 있습니다. 

* DOM 에서 element 가 addEventListenre을 사용할 수 있는 이유는 element가 EventTarget( Objec 이전 최상위 부모 클래스 )을 상속하고 있기 때문입니다. 

* DOM을 이용해서, document.createElement('div')를 통해 새로운 < div > 요소를 만드는 것도 HTMLDivElement 클래스에 속한인스턴스 생성입니다. ( Element라는 공통의 부모 ) 

* 모든 클래스의 최상위 부모 클래스는 Object 입니다. 

➡️ MDN_Object prototype

 

 

 

 

 

# 프로토타입과 체인

extends 키워드를 통해 상속 관계를 설정하고, 프로토타입을 통해 상속 관계를 구현합니다. 상위 클래스와 하위 클래스는 인스턴스의 프로토타입 체인 뿐만이 아니라, 클래스 간의 프로토타입 체인도 생성합니다. 상속의 상속의 상속의 느낌으로 이해하면 편할 것 같습니다. 

** 하나의 객체는 두 개의 객체를 상속 받을 수 없다.

** 하나의 상위 클래스는 여러 개의 하위 클래스를 상속할 수 있다.

 

 

상위 클래스 Human과 학생 클래스 Student  가 존재하고 학생 클래스가 Human 클래스를 상속 받는다고 가정해봅시다. 

// JS에서 상속하는 방법 
// 상위 Class : Human   // 하위 Class : Students

class Students extends Human {
	constructor( /*상위 클래스 속성 + 하위 클래스 속성*/ ){
    	super( /*상위 클래스 속성*/ );
        
        this.하위 속성 = 하위 속성;
    }
}

 

# 상위 클래스 [ Human ] 

 - 속성 : age, gender

- 메서드 : eat( ), sleep( )

 

# 하위 클래스 [ Students ]

- 속성 : age, gender, grade

- 메서드 : eat( ), sleep ( ), learn( )

* 하위 클래스에 선언 된 추가 속성과 메서드

* 하위 클래스에는 추가 속성과 메서드만 선언해주어도 상위 클래스로부터 상속받은 속성과 메서드를 사용할 수 있다는 것이 상속의 핵심 개념이었습니다. 

 

 

 

 

 

➡️참고01 :  MDN_Classes

➡️참고02 :  MDN_Prototypes

➡️참고03 : 모던 JS_프로토타입

➡️참고04 : 프로토타입을 이용하여 상속하기

➡️참고05 : 클래스

➡️참고06 : 

➡️