ABOUT ME

-

Today
-
Total
-
  • [생활코딩] JavaScript 객체지향 : 상속, Prototype, Object
    Study/JavaScript 2019. 12. 8. 18:06
    반응형

     

    상속

     

    객체는 연관된 로직들로 이루어진 작은 프로그램이라고 할 수 있다. 
    상속은 객체의 로직을 그대로 물려 받는 또 다른 객체를 만들 수 있는 기능을 의미한다. 

    기존의 로직을 수정하고 변경해서 파생된 새로운 객체를 만들 수 있게 해준다. 

    즉, 상속이란 부모의 기능을 자식이 물려받는 것이다.

     

    상속을 하게 되면?

    - 코드의 중복이 줄어든다.
    - 상속법 : 자식객체.prototype = new 부모객체(); 
    - 부모객체에서 프로퍼티들 정의할 때 prototype 붙여준다.
    - 기능 추가 역시 자식객체를 생성하고 prototype을 붙여서 프로퍼티를 정의한다.


    function Person(name){ 
        this.name = name; 
    } 
    Person.prototype.name=null; 
    Person.prototype.introduce = function(){ 
        return 'My name is '+this.name;  
    } 


    부모생성자를 정의한 후, 그 프로토타입객체에다 상속해줄 프로퍼티들을 정의한다.
     

    function Programmer(name){ 
        this.name = name; 
    } 
    Programmer.prototype = new Person(); 
    Programmer.prototype.coding = function(){ 
        return "hello world"; 
    } 

     

    자식생성자를 정의한 후, 그 프로토타입 프로퍼티로 부모생성자로 생성된 객체(인스턴스)를 지정한다.
     

    var p1 = new Programmer('egoing'); 


    자식생성자로 새로운 객체를 만든다. 이 객체는 부모생성자의 프로토타입에 있는 프로퍼티들을 상속받는다.

    console.log(p1.introduce());  // My name is egoing 
    console.log(p1.coding());  // hello world 
    

     

    Prototype

     

    Programmer는 Person의 기능을 가지고 있으면서 Person이 가지고 있지 않은 기능인 메소드 coding을 가지고 있다. 


    자바스크립트는 prototype based programming language 이다.

    prototype은 말 그대로 객체의 원형이라고 할 수 있다. 함수는 객체다. 그러므로 생성자로 사용될 함수도 객체다. 

    객체는 프로퍼티를 가질 수 있는데 prototype이라는 프로퍼티는 그 용도가 약속되어 있는 특수한 프로퍼티다. 

    prototype에 저장된 속성들은 생성자를 통해서 객체가 만들어질 때 그 객체에 연결된다. 

    자바스크립트는 prototype을 통해서 상속을 제공한다.
    객체의 변수, 함수에 대한 정보를 prototype이라는 속성에 저장하는데 그것은 객체 형태로 저장된다.
    부모 객체의 복제본을 만들어 그것을 자식객체에 상속하고,
    자식객체는 부모의 속성을 가진 채 동시에 자식만의 속성을 별도로 가질 수 있다.

    자식객체가 부모객체 프로퍼티에 접근 가능한 것은 prototype chain으로 부모와 자식이 연결되어 있기 때문이다. 
    prototype는 객체와 객체를 연결하는 체인의 역할을 하는 것이다. 이러한 관계를 prototype chain이라고 한다.


    function Ultra(){} 
    Ultra.prototype.ultraProp = true; 
      
    function Super(){} 
    Super.prototype = new Ultra(); 
      
    function Sub(){} 
    Sub.prototype = new Super(); 
      
    var o = new Sub(); 
    console.log(o.ultraProp);  // true
    


    => 객체 o에서 ultraProp를 찾는다.
    => 없다면 Sub.prototype.ultraProp를 찾는다.
    => 없다면 Super.prototype.ultraProp를 찾는다.
    => 없다면 Ultra.prototype.ultraProp를 찾는다.

     

    Object

     

    Object : 모든 객체가 상속하는 조상 객체


    Object가 가진 메소드는 두 가지 형태가 있다.

    Object.메소드이름()과 Object.prototype.메소드이름()인데

    첫 번째 형태는 Object 자신만 쓸 수 있고, 두 번째 형태는 모든 객체가 쓸 수 있다.

    그 이유는 모든 객체가 Object를 상속하기 때문이다.


    역으로 Object의 prototype을 이용해서 메소드를 만들면 모든 객체가 쓸 수 있는 강력한 메소드를

    만들 수 있지만 그만큼 위험해서 의도하지 않은 결과를 초래할 수 있기 때문에 되도록 권장하진 않는다.


    Object 객체는 객체의 가장 기본적인 형태를 가지고 있는 객체이다. 다시 말해 아무것도 상속받지 않는 순수한 객체다. 자바스크립트에서는 값을 저장하는 기본적인 단위로 Object를 사용한다.

    자바스크립트의 모든 객체는 Object 객체를 상속 받기 때문에, 모든 객체는 Object 객체의 프로퍼티를 가지고 있다.



    Object.keys()  &  Object.prototype.toString() 의 차이


    Object.keys(**)
    여기서 Object는 생성자 함수에 해당하고 **에 객체가 들어간다.
    즉, 함수처럼 사용되는 것이다.

     

    const object1 = {
      a: 'somestring',
      b: 42,
      c: false
    };
    
    console.log(Object.keys(object1));
    // expected output: Array ["a", "b", "c"]
    



    Object.prototype.toString() 
    여기서 Object는 생성자함수를 의미하며, toString이라는 메소드가 prototype의 소속으로 쓰이는 것이다.
    그래서 객체가 인자로 쓰이지 않고 객체에 대한 메소드를 사용한다.
    그리고 new Array로 배열 객체을 생성해도 위 toString 메소드를 쓸 수 있다.
    왜냐하면 Object는 모든 객체의 공통적인 부모이기 때문에 모든 객체는 object에 정의되어 있는 모든 메소드를 사용할 수 있다.

    var o = new Object();
    o.toString()
    // "[object Object]"
    function Dog(name) {
      this.name = name;
    }
    
    var dog1 = new Dog('Gabby');
    
    Dog.prototype.toString = function dogToString() {
      return '' + this.name;
    }
    
    console.log(dog1.toString());
    // expected output: "Gabby"


    즉, object.prototype 객체에 정의되어 있는 모든 메소드는 모든 객체가 공통적으로 사용할 수 있다.


    Object 객체는 사용자 정의에 따라 확장해나갈 수 있다.
    하지만 객체는 확장하지 않는 것이 바람직하다. 왜냐하면 모든 객체에 영향을 주기 때문이다. 

    이 문제를 회피하기 위해서는 프로퍼티의 해당 객체의 소속인지를 체크해볼 수 있는 hasOwnProperty를 사용하면 된다.
    hasOwnProperty는 인자로 전달된 속성의 이름이 객체의 속성인지 여부를 판단한다. 

    만약 prototype으로 상속 받은 객체라면 false가 된다.

    반응형

    댓글