나만보는개발공부블로그

classical & prototypal inheritance in javascript 본문

Javascript&Typescript

classical & prototypal inheritance in javascript

alexrider94 2021. 2. 22. 23:09

제목과 같은 classical한 상속과 ingeritance한 상속에 관한 패러다임에 대해서 알아보자.

자바스크립트에서의 OOP같은 code들을 사용할떄는 전부 Prototypal Inheritance라고 할 수 있다.

아래의 그림처럼 단계로 쉽게 나눠볼 수 있다.

                                   Inheritance
                                        |
                         +-----------------------------+
                         |                             |
                         v                             v
                    Prototypal                     Classical
                         |
         +------------------------------+
         |                              |
         v                              v
Prototypal Pattern             Constructor Pattern

-Classical Inheritance의 대표적인 언어로는 C++,Java 그리고 c#이 있다.

-Prototypal Inheritance의 대표적인 언어로는 Self, Lua 그리고 Javascript가 있다.

 

Object-Oriented Programming

위의 두가지 상속법은 모두 OOP(Object-Oriented Programming)에 속한다. Object는 일종의 실제 세계의 어떤 개체를 속성들의 추상화한것이라고 생각하면 된다.

 

* 추상화 : 컴퓨터 프로그램에서 실제 세계(real world)의 것을 표현하는 법.

 

어떤 객체는 여러가지의 공통된것들이 많은데 예를 들어서 자동차는 포르쉐, 현대차 등 다양한 차들이 있고 이것들을 공통으로 차라고 일반화할 수 있다. 포르쉐와 현대차는 전부 추상화들이다. 하지만 차는 포르쉐나 현대차보다 조금 더 일반적인 추상화적이다. 

* 일반화 : 어떤 상세한 추상화보다 더 추상화 된 것

 

OOP에서 우리는 위의 예시같은 일반화들을 생성하기위해 객체들을 생성하고 클래스나 프로토타입을 사용한다.

일반화들은 상속을 통하여서 생성된다. 예시로 차는 포르쉐의 일반화이고 그러므로 포르쉐는 차로부터 상속되었다.

 

Classical Object-Oriented Programming

Classical OOP에서는 두가지의 추상화가 있는데 Classes와 Objects이다. Object는 실제 세계의 entity를 추상화 한 것이고 Class는 Object나 다른 Classes를 추상화 한 것이다. 

+----------------------+----------------+---------------------------------------+
| Level of Abstraction | Name of Entity |                Comments               |
+----------------------+----------------+---------------------------------------+
| 0                    | John Doe       | Real World Entity.                    |
| 1                    | johnDoe        | Variable holding object.              |
| 2                    | Man            | Class of object johnDoe.              |
| 3                    | Human          | Superclass of class Man.              |
+----------------------+----------------+---------------------------------------+

위의 예시를 보면 Classical OOP에서의 objects들은 전부 추상화이다.(모든 objects들은 abstraction level 1)그리고 classes들은 오직 일반화되어있다.(모든 clasees들은 abstraction level1보다 큼)

 

class Human {
    // ...
}

class Man extends Human {
    // ...
}

Man johnDoe = new Man();

요약하면 classical OOP에서는 모든 Objects들은 실제 세계의 entities들에 대해서 추상화되어있고 classes들은 전부 일반화되어있다. 따라서 추상화 수준이 증가하면 entities들은 점점 더 general(일반화)이게 되고 추상화 수준이 감소하면 entities들이 점점더 specific(구체적)으로 변한다.

Prototypal Object-Oriented Programming 

Prototypal OOP는 Classical OOP보다 더 심플하다. 왜냐하면 Prototypal OOP에서 우리는 오직 하나의 추상화(예시로 objects)를 가지기 때문이다. 

+----------------------+----------------+---------------------------------------+
| Level of Abstraction | Name of Entity |                Comments               |
+----------------------+----------------+---------------------------------------+
| 0                    | John Doe       | Real World Entity.                    |
| 1                    | johnDoe        | Variable holding object.              |
| 2                    | man            | Prototype of object johnDoe.          |
| 3                    | human          | Prototype of object man.              |
+----------------------+----------------+---------------------------------------+

위의 예시를 보면 Prototypal OOP에서의 objects들은 실제세계의 entities들이나 다른 objects들의 추상화이다. 그래서 prototype은 일반화라고 할 수 있다.

var human = {};
var man = Object.create(human);
var johnDoe = Object.create(man);

위의 예시처럼 Prototypal OOP에서의 Objects들은 아무것도 없는 상태에서나 다른 object으로 부터 생성될 수 있다.

 

Prototypal OOP가 classical OOP보다 더 강력하다고 생각하는 이유로는

1. 오직 하나의 추상화만 있다.

2. 일반화는 간단하게 Objects이다.

 

Prototypal 과 classical의 다른점은 classical은 클래스의 상속은 다른 클래스에서 상속된 클래스로 제한되지만 prototypal에서 프로토타입 상속은 다른 프로토타입에서 상속 된 프로토 타입뿐 아니라 프로토 타입에서 상속된 객체도 포함한다.

 

실제로 프로토타입과 클래스는 매우 비슷하고 아래 코드처럼 사용될 수 있다.

function CLASS(base, body) {
    if (arguments.length < 2) body = base, base = Object.prototype;
    var prototype = Object.create(base, {new: {value: create}});
    return body.call(prototype, base), prototype;

    function create() {
        var self = Object.create(prototype);
        return prototype.hasOwnProperty("constructor") &&
            prototype.constructor.apply(self, arguments), self;
    }
}

위의 CLASS 함수는 클래스처럼 보이는 프로토타입을 생성할 수 있다.

var Human = CLASS(function () {
    var milliseconds = 1
      , seconds      = 1000 * milliseconds
      , minutes      = 60 * seconds
      , hours        = 60 * minutes
      , days         = 24 * hours
      , years        = 365.2425 * days;

    this.constructor = function (name, sex, dob) {
        this.name = name;
        this.sex = sex;
        this.dob = dob;
    };

    this.age = function () {
        return Math.floor((new Date - this.dob) / years);
    };
});

var Man = CLASS(Human, function (Human) {
    this.constructor = function (name, dob) {
        Human.constructor.call(this, name, "male", dob);
        if (this.age() < 18) throw new Error(name + " is a boy, not a man!");
    };
});

var johnDoe = Man.new("John Doe", new Date(1970, 0, 1));

프로토타입을 모델링 하는데 클래스를 사용할 수 없다. 프로토 타입은 객체이지만 클래스는 객체가 아니기 때문이다. 이 둘은 완전히 다른 유형의 추상화이다.

 

stackoverflow.com/questions/19633762/classical-inheritance-vs-prototypal-inheritance-in-javascript

 

classical inheritance vs prototypal inheritance in javascript

I have googled so many links and can't get good idea about the difference between classical inheritance and prototypal inheritance? I have learned some things from these but I'm still confused abo...

stackoverflow.com

 

'Javascript&Typescript' 카테고리의 다른 글

Iterable & Iterator  (0) 2021.02.23
FP & OOP  (0) 2021.02.22
Declarative and Imperative programming  (0) 2021.02.21
Closure  (0) 2021.02.19
Event loop - 2  (0) 2021.02.17