본문 바로가기

JAVASCRIPT

[자바스크립트] 클래스 / 프로토타입 / 생성자

자바스크립트에서 상속이란, 현재 존재하고 있는 객체를 프로토타입을 사용해, 해당 객체를 복제해 재사용하는 것 

자바스크립트 클래스는 프로토타입기반 상속을 사용 (= 객체지향에서 사용되는 클래스)

 * 같은 클래스의 인스턴스 = 두 객체가 같은 프로토타입에서 프로퍼티를 상속

 * 인스턴스(instance) :  비슷한 성질을 가진 여러 객체를 만들기 위해서, 여러 생성자 함수(클래스 / 프로토타입)를 사용해 만들어낸 것

이러한 인스턴스는 원래 객체인 클래스 or 프로토타입이 가지고 있는 프로퍼티 + 메소드를 모두 상속받음!

 


클래스와 프로토타입

클래스란, 같은 프로토타입 객체에서 프로퍼티를 상속하는 객체의 집합

* 아래는 단순한 자바스크립트 예시 

// Range객체를 반환하는 factory function(팩토리 함수) 
 function range(from, to) {
	// 아래에서 정의하는 프로토타입 객체를 상속하는 객체를 생성함 
    // 프로토타입 객체는 이 함수의 프로퍼티로 저장, Range객체에서 공유하는 메서드를 정의
    let r = Object.create(range.methods);
    
    // Range객체의 시작과 끝을 저장 
    // 이 객체에 대한 고유 프로퍼티이므로, 상속되지 않음 
    r.from =from;
    r.to = to;
    
    return r; // 새 객체 반환 
    }
    
    // Range 객체가 상속하는 메서드 정의
    range.methods = {
    	// x가 범위 안에 있다면 true, 그렇지 않다면 false를 반환 
         includes(x) {return this.from <= x &&& x <= this.to; },
         
        // 클래스 인스턴스를 이터러블로만드는 제너레이터함수 
        *[Symbol.iterator]() {
        	for(let x  =Math.cell(this.from); x <= this.to; x++) yield x ;
            },
            // 범위를 나타내는 문자열을 반환함 
            ToString() {return "(" + this.from + "..." + this.to + ")";} 
            };
            
          // Range 객체의 사용 예제
           let r = range(1,3); 
            r.includes(2) // => true // 2는 범위 안에있음 
            [...r] // 이터레이터를 통해 배열로 반환

 

클래스와 생성자

생성자, 새로 생성된 객체를 초기화하도록 설꼐도니 함수 ( new 키워드 사용해 새 객체 생성)

생성자의 프로토타입 프로퍼티가 새 객체의 프로토타입으로 사용됨 (함수 객체)

 

 * ES6의 클래스 키워드를 지원하지 않는 자바스크립트 버전에서 사용 

    1) 클래스 이름은 관습적으로 대문자(Range), 함수와 메서드 이름은 소문자로 작성함 

    2) Range() 생성자를 new 키워드와 함께 호출 (생성자를 호출하면 새 객체 생성, 객체의 메서드로 생성자 호출)  

    3) Range() 생성자는 this로 초기화 가능

// 생성자를 사용해 작성한 Range 클래스
// 객체를 초기화하는 생성자 함수 

function Range (from, to){
	// Range 객체의 시작점과 끝점을 저장함 
    // 이 객체의 고유한 프로퍼티이므로 상속되지 않음 
    this.from = from;
    this.to = to;
    } 
    
    // Range객체는 모두 이 객체를 상속함 
    // 코드가 동작하기 위해서는 프로퍼티 이름이 반드시 프로토타입이어야 함 
    Range.prototype = {
    	// x가 범위 안에 있으면  true를, 그렇지 않으면 false를 반환
        // 메서드는 숫자뿐만이 아닌 텍스트/ 날짜에도 동작함 
        includes : function (x) {return this.from <= x&& <= this.to;},
        
        // 클래스 인스턴스를 이터러블로 만드는 제너레이터 함수 
        [Symbol.iterator] :function*() {
        	for (let x = Math.ceil(this.from); <=this.to ; x++) yield x ;
            };
            
            // 범위를 나타내는 문자열을 반환 
            toString : function() {return "(" + this.from + "..." + this.to + ")";}
            };
            
       // Range 클래스 사용 
       let r = new Range(1,3); // Range객체 만들기 
       r.includes(2)  // true

 

※ new.target 

함수가 생성자로 호출되었는지 알 수 있는 표현식     

undefined값으로 나타나지 않는다면 함수는 new키워드와 함께 생성자로 호출된 것 / 나타난다면 함수로 호출된 것

클래스 키워드로 생성된 클래스는  new 생성자 없이 생성자 호출이 가능함 


생성자, 클래스의 본질 

객체가 클래스의 멤버인지 확인할 때 instance of를 사용해 작성

e.g.  객체 r이 range의 객체인지 확인하고 싶을 때,    r instanceof Range  // true 

 

객체의 프로토타입 체인에 특정 프로토타입이 존재하는지 테스트할 때, isPrototypeOf() 사용 (생성자 함수 기준 X) 

 

 

 

 

 

728x90