ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Node.js] 객체 생성과 상속
    programing/Language 2019. 1. 14. 22:21

    안녕하세요, Einere입니다.

    (ADblock을 꺼주시면 감사하겠습니다.)


    오늘은 Node.js에서, 객체를 생성하는 방법과 상속에 대해 알아보겠습니다.

    ES6에 들어서면서, 기존의 객체지향 언어와 비슷하게 class, extends등의 키워드가 도입되었습니다.

    하지만 그것들은 syntax sugar이며, 내부 동작도 기존의 프로토타입 기반 동작과 다릅니다.

    그래서 프로토타입 기반에 충실하여, 프로토타입을 이용한 생성과 상속에 대해 알려드리겠습니다.




    객체 생성

    // a ---> Object.prototype ---> null
    const A = function(){
        this.aa = 1;
    }
    const a = new A();

    위와 같이 생성자 함수를 정의한 후, new 키워드를 이용해 생성하면 됩니다.

    A생성자는 instance가 key가 aa며 value가 1인 속성을 가지도록 합니다.


    A생성자를 이용해 생성한 a객체는 A의 instance입니다.




    상속

    // b ---> a ---> Object.prototype ---> null
    const B = function(){
        A.call(this);
        this.bb = 2;
    }
    B.prototype = Object.create(A.prototype);
    B.prototype.constructor = B;
    const b = new B();

    B생성자는 A와 유사하게 key가 bb이며 value가 2인 속성을 가지도록 합니다.

    거기다가, A.call(this)를 추가하여, A의 속성인 aa도 B가 가질 수 있도록 합니다.


    모든 객체는 prototype이라는 속성을 가지고 있습니다.

    Object.create()를 사용하여, B는 A의 prototype을 상속받습니다.

    또한, 생성자를 A가 아닌 B로 설정하기 위해, B.prototype.constructor에 B를 대입합니다.


    B를 이용해 생성된 b객체는 B의 instance입니다.



    // c ---> b ---> a ---> Object.prototype ---> null
    const C = function(){
        B.call(this);
        this.cc = 3;
    }
    C.prototype = Object.create(B.prototype);
    C.prototype.constructor = C;
    const c = new C();

    마찬가지로 C생성자를 이용해 c를 생성합니다.




    확인

    console.log(a);
    console.log(b);
    console.log(c);
    console.log(c.aa);
    console.log(c.bb);
    console.log(c.cc);
    console.log(c instanceof A);
    console.log(c instanceof B);
    console.log(c instanceof C);
    console.log(c.hasOwnProperty('aa')); 
    console.log(c.hasOwnProperty('bb'));
    console.log(c.hasOwnProperty('cc'));

    이제 각 instance와 속성, 어느 생성자의 instance인지, 특정 속성을 가지고 있는지 확인해보도록 하겠습니다.




    a는 aa속성을 가진 A객체, b는 bb속성을 가진 B객체, c는 cc속성을 가진 C객체라고 나오네요.

    c의 aa, bb, cc속성을 출력해보니 1, 2, 3이 출력됩니다.

    c는 A, B, C의 instance라고 출력됩니다.




    B와 C의 constructor를 재정의 하지 않는다면?


    생성자 B와 C의 prototype.constructor를 각각 B와 C로 재정의 하지 않는다면, b와 c는 A객체인것으로 나타나게 됩니다.




    c객체의 aa속성과 bb속성을 숨기는 방법은?


    위 사진과 같이 c객체가 aa와 bb속성을 가지지 않는데도 출력가능하게 하려면 어떻게 해야 할까요?


    // c ---> b ---> a ---> Object.prototype ---> null
    const C = function(){
        // B.call(this);
        this.cc = 3;
    }
    C.prototype = b;
    // C.prototype.constructor = C;
    const c = new C();

    생성자 함수 내부의 call()함수 호출부분과 constructor에 생성자 함수를 대입하는 부분을 주석처리 합니다.

    그리고 prototype에 Object.create()의 결과값을 대입하는 대신, instance를 대입합니다.


    그렇다면, 어떻게 c가 가지고 있지 않은 속성을 출력할 수 있을까요?

    그 이유는 c가 가지고 있지 않은 속성은, 상속받은 부모 객체에서 찾기 때문입니다.

    c는 bb속성을 가지고 있지 않기 때문에, c.prototype을 통해 부모 객체인 b에 접근합니다.

    마찬가지로 c는 aa속성을 가지고 있지 않기 때문에 부모 객체 b에 접근하고, 부모 객체 b에도 aa속성이 존재하지 않으므로 b.prototype을 통해 부모 객체 a에 접근합니다. 

    부모객체 a는 aa속성을 가지고 있기 때문에 1이라는 값을 출력할 수 있습니다.




    a객체와 b객체에도 존재하지 않는 d라는 속성을 출력하려고 한다면?

    만약 a, b에도 존재하지 않는 dd라는 속성을 찾고자 하면 어떻게 될까요?

    그러면 결국 최상위 부모 객체인 Object까지 찾게 되며, Object의 prototype은 null이므로 탐색이 종료됩니다.

    탐색이 끝날 때 까지 d라는 속성을 발견하지 못한다면, undefined를 출력하게 됩니다.

    댓글

Designed by black7375.