ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Section 13. 자바스크립트 프로토타입의 개념
    자바스크립트 2023. 4. 8. 16:25

    I. 프로토타입 prototype

    • 자바스크립트는 프로토타입 기반의 객체지향 프로그래밍을 지원하는 언어

    자바스크립트의 모든 객체는 Prototype을 가진다.

    const obj = {};
    
    console.log(obj);

    toString이나 valueOf 같은 함수들을 그냥 가져다 쓸 수 있는 이유도 프로토타입 때문이다.

     

    II. Object - 모든 객체의 조상

    아래의 객체들은 모두 프로토타입을 가지고 있고 그 프로토타입들은 결국 Object 에서 파생된 것을 확인할 수 있다.

    console.log(
      new String('')
    );
    
    console.log(
      []
    );
    
    console.log(
      new Map()
    );

    constructor 항목에서 각각의 생성자를 확인할 수 있다. 

    객체 리터럴 ( {} )등의 생성자는 Object이다.

     

    프로토타입 체인

    특정 객체에 호출된 프로퍼티가 없다면 프로토타입을 거슬러 올라간다.

    만약 Array에는 valueOf가 없지만 그 프로토타입인 Object에는 있으므로 호출이 가능하다.

    III. 코드로 프로토타입에 접근하기

    1. Object.getPrototypeOf

    수정할 때는 __Proto__보다 이 기능을 사용하는 것이 좋다.

    console.log(
      Object.getPrototypeOf({})
    );
    
    console.log(
      Object.getPrototypeOf([]) === [].__proto__
    ); //true

    첫 번째 출력문은 다음과 같다.

    2. 생성자 함수에서는 Prototype으로 프로토타입에 접근이 가능하다

    즉, function 으로 선언된 함수들에서

    function Person (name) {
      this.name = name;
    }
    
    // 인스턴스들에 공유될 프로토타입에 다음과 같이 접근
    console.log(Person.prototype);
    
    const hong = new Person('홍길동');
    
    console.log(hong);

    두 번째 출력문은 다음과 같다

    세 번째 출력문은 다음과 같다

    [[Prototype]] 이 두 단계로 있는 것을 확인 가능하다. (Person - Object)

    IV. 인스턴스 vs 프로토타입 프로퍼티

    function KangChicken (name, no) {
      this.name = name;
      this.no = no;
      this.introduce = function () {
        return `안녕하세요, ${this.no}호 ${this.name}점입니다!`;
      }
    }
    
    const chain1 = new KangChicken('판교', 3);

    생성자 함수 KangChicken를 통해 chain1이라는 인스턴스를 생성했다.

    KangChicken.prototype.introEng = function () {
      return `Welcome to Kang Chicken at ${this.name}!`;
    };
    
    console.log(chain1.introEng()); //Welcome to Kang Chicken at 판교!
    console.log(new KangChicken('강남', 17).introEng()); //Welcome to Kang Chicken at 강남!

     생성자 함수에 새로운 기능을 추가했다. 그리고 인스턴스의 로그를 펼쳐보면 다음과 같다

    console.log(chain1);

    introduce 함수는 인스턴스가 생성될 때마다 존재한다.

    introEng 함수는 프로토타입에만 존재한다. 즉, 메모리 절약이 된다.

     

    메모리 사용을 최소화 하려면 다음과 같다

    function KangChicken (name, no) {
      this.name = name;
      this.no = no;
    }
    
    // 공통된 요소들은 프로토타입 프로퍼티로
    KangChicken.prototype.titleEng = 'KangChicken';
    
    KangChicken.prototype.introduce = function () {
      return `안녕하세요, ${this.no}호 ${this.name}점입니다!`;
    }
    
    KangChicken.prototype.introEng = function () {
      return `Welcome to ${this.titleEng} at ${this.name}!`;
    };
    const chain1 = new KangChicken('판교', 3);
    const chain2 = new KangChicken('강남', 17);
    const chain3 = new KangChicken('제주', 24);
    
    console.log(chain1.introduce()); //안녕하세요, 3호 판교점입니다!
    console.log(chain1.introEng()); //Welcome to KangChicken at 판교!

    인스턴스 레벨과 프로토타입 프로퍼티들을 비교하면 다음과 같다

    console.log(chain1, chain2, chain3);

    introEng 함수와 introduce 함수가 모두 프로토타입 밑에 존재하는 것을 확인할 수 있다.

     

    프로토타입 레벨의 함수를 인스턴스 레벨에서 덮어쓰기가 가능하다.

    const chain4 = new KangChicken('평양', 456);
    chain4.introduce = function () {
      return `어서오시라요, ${this.no}호 ${this.name}점입네다!`;
    }
    
    
    console.log(chain4.introduce()); //어서오시라요, 456호 평양점입네다!

     

Designed by Tistory.