개발/Javascript

[You don't know JS] Part3 - 4장. 클래스와 객체의 혼합

lanace 2020. 9. 6. 06:42

객체지향 프로그래밍 (OOP, Object oriented progamming)에 대해 알아보자

인스턴스화, 상속, 다형성 등 클래그 관련 기법들을 살펴보기 전에, 클래스 지향을 디자인 패턴으로 조명해보자.

클래스 지향 개념은 자바스크립트와 잘 맞지않는 부분이 있어 헷갈린다.

4.1 클래스 이론


클래스와 상속은 특정 형태의 코드와 구조를 형성하며 실행활 영역의 문제를 소프트웨어로 모델링 하기 위한 방법이다.

자세한건 OOP 관련된 책에서 확인

4.1.1 클래스 디자인 패턴

클래스를 디자인 패턴이라고 생각해본적이 없음.

절차 지향형 프로그래밍을 좀더 체계적으로 바꾼 일종의 디자인 패턴이다.

4.1.2 자바스크립트의 클래스

일단 Javascript에서 클래스는 없다.

⇒ 비슷하게 프로토타입을 사용하여 흉내낼 뿐이다.

어쨋든 클래스는 일종의 디자인 패턴이니 사용할지 말지는 선택하는 것이다.

4.2 클래스 체계


4.2.1 건축

클래스와 인스턴스의 관계를 건축에 비교를 많이 한다.

4.2.2 생성자

인스턴스는 보통 클래스명과 같은 이름의 생성자라는 특별한 메서드로 생성한다.

생성자는 인스턴스에 필요한 정보를 초기화 한다.

4.3 클래스 상속


4.3.1 다형성

4.3.2 다중 상속

4.4 믹스인


자바스크립트 객체는 상속받거나 인스턴스화 해도 자동으로 복사 작업이 일어나지는 않는다.

클래스란 개념 자체가 없고 오직 객체만 있다.

객체는 다른 객체에 복사된게 아니라 연결되어있는거 뿐이다.

명시적 믹스인과 암시적 믹스인에 대해 알아보자

4.4.1 명시적 믹스인

function mixin(sourceObj, targetObj) {

    for (var key in sourceObj) {
        if (!(key in targetObj)) {
            targetObj[key] = sourceObj[key];
        }
    }
}

function Vehicle = {
    engines: 1,

    ignition: function () {
        console.log('엔진을 켠다')    ;
    },

    drive: function () {
        this.ignition();
        console.log('방향을 맞추고 간다.');
    }
}

var Car = mixin(Vehicle, {
    wheels: 4,
    drive: function() {
        Vehicle.drive.call(this);
        console.log(this.wheels + '개의 바퀴로 굴러간다요');
    }    
})

Car에는 vehicle에서 복사한 프로퍼티와 함수 사본이 있다.

레퍼런스만 복사된거다.

그래서 ignition이 들어있긴 하다.

mixin에서 drive는 이미 Car에서도 재정의 했기떄문에 중복으로 복사되지 않는다.

다형성 재고

Vehicle.drive.call(this); 와 같은 코드를 명시적 의사다형성 이라 한다.

자바스크립트는 상대적 다형성은 지원하지 않는다.

Vehicle과 Car를 구별해서 사용할 수 없다는것이다.

따라서 절대적인 레퍼런스를 이용할 수 밖에 없고, Vehicle 객체의 이름일 지정하여 사용한 것이다.

⇒ 결론

자바스크립트는 다형적 레퍼런스가 필요한 함수마다 명시적 의사 다형성 방식의 취약한 연결을 명시적으로 일일이 만들어줄 수 밖에 없다.

따라서 유지비용이 크고, 다중 상속 작동 망식을 모방할 수 있어 복잡도와 취약성이 높다.

결과적으로 더 복잡하고, 읽기 어렵고 관리하기 어려운 코드가 된다.

사본 혼합

기생 상속

4.4.2 암시적 믹스인

var Something = {
    cool: function () {
        this.greeting = 'hello world';
        this.count = this.count ? this.count + 1 : 1;
    }
}

Something.cool();
Something.greeting;  'hello world'
Something.count;  // 1

var Another = {
    cool: function () {
        Something.cool.call(this);
    }
}

Another.cool();
Another.greeting;  'hello world'
Another.count;  // 1

call을 사용하여 Something을 빌려와 사용할 수 있다.

this 만 바꿔서 사용한다.

하지만 불안정하므로 사용할 떄 신중히 해야하며 관리하기 어렵우므로 잘 쓰지 말자

4.5 정리하기