IT/JS

프로토타입(prototype)에 대하여

프티 2021. 8. 20. 08:07
반응형

JS에서는 객체를 상속하기 위하여 prototype이라는 방식을 사용한다.

 

이번 포스팅에서는 프로토타입 체인이 동작하는 방식을 알아보고,

이미 존재하는 생성자에 메소드를 추가하기 위해 프로토타입 속성을 사용하는 방법을 정리해보겠다.

 

또한 function의 타입이 Object가 아닌 function으로 나오는 이유도 알아보겠다.

 

JS는 프로토타입 기반 언어이다.

모든 객체들은 프로토타입 객체를 가진다.

프로토타입 객체는 또 다시 상위 프로토타입 객체를 가질 수 있으며 이를 프로토타입 체인이라고 부른다.

 

프로토타입 체인은 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 하는 근간이 된다.

정확히 말하자면 상속되는 속성과 메소드들은 객체의 생성자의 프로토타입이라는 속성에 정의되어 있다.

 

생성자에 의해 만들어진 객체 인스턴스와 프로토타입 간에 연결이 구성된다.

이때 대부분의 브라우저들이 생성자의 프로토타입 속성에서 파생된 ' __proto__ ' 속성으로 객체 인스턴스에 구현하고 있다.

 

이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색한다.


 

prototype 속성과 __proto__의 차이는?

prototype은 생성자의 프로토타입 속성이고,

__proto__는 인스턴스의 프로토타입 속성이다.


프로토타입 체인을 구현하려면 프로토타입 객체에 대한 링크가 필요하다.

이 링크는 프로토타입 객체의 내부 슬롯이라고 불리는 곳에 [[prototype]]에 정의되어 있다.

 

모든 객체에는 내부 슬롯에 [[prototype]] 속성이 정의되어 있다.

 

function이 object가 아닌 function으로 나오는 이유

객체에는 내부 슬롯 뿐만 아니라 내부 메소드도 존재한다.

 

내부 메소드는 다형성을 가지며 각기 다른 객체 값이 다른 알고리즘을 수행할 수 있다.

만약 지원하지 않는 메서드를 실행할 경우 TypeError를 반환한다.

 

자바스크립트 객체의 필수 내부 메서드는 다음과 같다.

[[GetPrototypeOf]], [[SetGPrototypeOf]], [[IsExtensible]], [[PreventExtensions]], [[GetOwnProperty]], [[DefineOwnProperty]], [[HasProperty]], [[Get]], [[Set]], [[Delete]], [[OwnPropertyKeys]]

 

함수도 객체이므로 위에 나열한 메서드를 모두 가지고 있다.

 

하지만, 함수는 일반 객체와 다르게 호출이 가능하다.

왜냐하면 함수는 함수로서 동작하기 위한 [[Environment]], [[FormalParameters]] 등의 내부 슬롯과 [[Call]], [[Construct]] 같은 내부 메서드를 추가로 갖고 있기 때문이다.

 

내부 메서드에 [[call]]이 존재하면 typeof를 하였을 때 function을 반환한다.

 

그렇다면 자바스크립트는 어떻게 이 객체가 함수인 것을 알고 [[call]] 메서드를 생성하는 것일까!

 

답은, 해당 객체가 함수 정의 방법을 통해 실행되었을 때 [[call]]이 호출된다.

그리고 [[constructor]]는 객체를 생성할 때, super(아직 잘 모름)나 new 연산자가 실행되었을 때 호출한다.

 

함수 정의 방법에는 함수 선언문, 함수 표현식, 화살표 함수, Function 생성자 함수 이렇게 4가지가 존재한다.

 

여기서 [[constructor]]를 가지는 방식이 있고 [[non-constructor]]를 가지는 방식이 있다.

  • [[constructor]]
    함수 선언문, 함수 표혀식, 클래스
  • [[non-constructor]]
    화살표 함수, 메서드(ES6 메서드 축약 표현)

    메서드 축약 표현이란?
    ES5에서 메소드를 선언하려면 프로퍼티 값으로 함수 선언식을 할당했지만,
    ES6에서는 메소드를 선언할 때, function 키워드를 생략한 축양 표현을 사용할 수 있다.
    // ES6
    const obj = {
      name: 'Lee',
      // 메소드 축약 표현
      sayHi() {
        console.log('Hi! ' + this.name);
      }
    };
    
    obj.sayHi(); // Hi! Lee​

constructor가 있는 함수는 일반 함수로 호출이 가능하면서 생성자 함수로 호출할 수 있는 반면에,

non-constructor인 함수는 일반 함수와 생성자 함수로 호출할 수 없다.

 

 

출처

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_prototypes

 

Object prototypes - Web 개발 학습하기 | MDN

Javascript에서는 객체를 상속하기 위하여 프로토타입이라는 방식을 사용합니다. 본 문서에서는 프로토타입 체인이 동작하는 방식을 설명하고 이미 존재하는 생성자에 메소드를 추가하기 위해

developer.mozilla.org

 

https://www.howdy-mj.me/javascript/prototype-and-proto/

 

[[Prototype]], __proto__와 prototype

자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어다. ES6에서 Class(이하 클래스)가 도입되긴 했지만, 다른 언어에서 사용되는 클

www.howdy-mj.me

 

반응형