ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로토타입 - 기본
    개발/Javascript 2022. 3. 1. 02:29

    자바스크립트의 프로토타입 기반의 언어입니다.

    웹은 실무 경험이 아직 깊지 않기 때문에

    왜 필요한지 어떻게 써야 하는지 등에 대한 부분을 아직 깊이 있게 겪어보지 못했습니다.

    그러므로 관련한 내용은 이 글에서 언급하지 않겠습니다.

    기술, 문법적인 부분에 국한해서 설명드리겠습니다.

     

    자바스크립트의 일부 객체는 함수를 통해 생성됩니다.

    const obj = {};
    const arr = [];

    위 코드 어디에도 함수가 보이지 않지만 리터럴이라는 문법으로 통해 편하게 객체를 만들어도

    내부적으로는 함수를 호출합니다. 어떤 함수일까요.

    다음 코드와 의미가 같습니다.

    const obj = new Object();
    const arr = new Array();

    obj의 정체는 크롬 브라우저에서 확인이 가능한데요.

    생성자가 Object()라는 점에서 obj 객체는 Object 함수로 만들어졌다는 걸 알 수 있습니다.

    arr도 살펴볼까요.

    배열 역시 Array() 함수를 생성자로 가지고 있습니다.

     

    함수를 정의하면 해당 함수를 정의하는 생성자 함수가 만들어지기 때문에

    생성자 함수와 해당 객체를 만드는 함수가 같습니다.

     

    원시 자료형이 경우에는 따로 생성자가 없으므로 객체도 아니며 메소드를 가지지 않는 데이터입니다.

    string, number (en-US), bigint (en-US), boolean, undefined, symbol, 그리고 null이 존재합니다.

     

    예시 하나를 더 들어볼게요.

    정의부가 비어 있는 Func 함수를 만들어 살펴보겠습니다.

    생성자에 Func()가 표기되어 있습니다.

    함수를 정의할 때 생기는 생성자는 함수 자신이라는 특성이 있습니다.

    때문에 리터럴로 객체를 만들고 배열을 만들었을 때

    해당 객체들이 함수를 통해 만들어진 것을 알 수 있었던 것입니다.

     

    이미지들을 자세히 보면 공통적으로 프로토타입이라는 글자가 보이는데요.

    사용자 정의 함수에만 prototype이라는 객체가 하나 더 보이고

    객체, 배열 객체, 함수에는 공통적으로 [[Prototype]]이 보입니다.

    대부분의 브라우저에서 [[Prototype]]은 __proto__라는 이름으로 구현되어 있어요.

    이게 대체 뭘까요? 일단 표준은 아닙니다.

     

    먼저 [[Prototype]]을 알아봅시다. 자바에서 모든 클래스가 Object를 상속하고 있는 것과 비슷합니다.

    객체든 배열 객체든 선언을 해서 내부를 보면 정의한 적 없는 각종 함수들이 내장되어 있습니다.

    배열 객체를 예로 들어볼게요.

    배열 객체는 Array 함수를 통해 만들어집니다.

    리터럴을 통해 축약된 문법으로 생성할 수 있지만 new Array()를 통해서 만드는 것과 동일합니다.

    const arr = []; // const arr = new Array();

    arr의 배열 객체에 map 같은 내장함수를 사용할 수 있는 이유는 [[Prototype]]을 통해 Array 함수에 접근할 수 있기 때문입니다. 이렇게도 표현할 수 있습니다. Array 함수의 속성이 상속됐다고. 그리고 [[Prototype]]은 대부분의 객체에서 __proto__로 표현되며  arr.__proto__를 보면 Array() 내장함수들을 볼 수 있습니다.

    여기서 한 가지 더 나아갈 것이 있는데요. 일반 객체의 경우에는 [[Prototype]]이 Object 함수를 가리킵니다.

    arr 배열의 __proto__역시도 객체이기 때문에 __proto__의 [[Prototype]]은 Object를 가리킵니다.

    이렇게 반복되면서 거슬러 올라가는 것을 프로토타입 체인이라고 합니다.

     

    다음을 보시면 좀 더 명확합니다. Object는 최상위의 부모이기 때문에 Object 함수의 [[Prototype]]은 null입니다.

    이렇게 프로토타입 체인이 종료됩니다.

     

    사용자 정의 함수는 prototype 객체가 있다고 했는데요.

    prototype 객체에는 생성자와 [[Prototype]]을 가집니다.

    Person이라는 함수를 만들고 나서 나중에 이름을 리턴해야 하는 함수를 추가해야 한다고 할 때

    모든 Person 객체마다 getName()을 추가하면 객체마다 새로 생성되는 함수만큼 메모리를 차지하게 되는데요.

    Person.prototype에 getName()을 추가하면 메모리 낭비를 막을 수 있게 됩니다.

    function Person(name) {
        this.name = name;
    }
    
    const kim = new Person('kim');
    const lee = new Person('lee');
    
    Person.prototype.getName = function() {
        return this.name;
    }
    
    kim.getName(); // kim
    lee.getName(); // lee

    그리고 prototype 역시 객체이므로 prototype의 [[Prototype]]은 Obeject입니다.

    '개발 > Javascript' 카테고리의 다른 글

    reduce를 이용해 배열 객체를 하나의 객체로 만들기  (0) 2022.04.26
    키보드 입력  (0) 2022.03.30
    var, function  (0) 2022.02.26
    this  (0) 2022.02.26
    [tailwindcss] 최초 설정  (0) 2022.01.31

    댓글

Designed by Tistory.