프로토타입 (Prototype)

song·2023년 12월 26일
0

js 정보

목록 보기
28/30

상속

js에서 상속은 다른 객체 지향 언어의 클래스 상속과 다름

대부분의 객체 지향 언어의 클래스 상속은 복사의 형태지만 js에서 상속은 프로토타입 기반 상속(프로토 체이닝)

클래스에서 상속

  • 부모 인스턴스가 복사되어 자식 인스턴스에 생김
    (부모 인스턴스 + 자식 인스턴스 되어 자식에게 생김)

js에서 상속

  • 복사를 의미 X
  • 이유: js는 깊은 복사를 지원하지 않기 때문
    그래서 상속을 흉내내기 위해 객체가 연결을 기반으로 작동함
    여기서 연결은 __proto__를 뜻함

프로토타입은 클래스, 객체의 내용 복사 없이도 상속을 구현할 수 있게 해주는 방법
프로토타입은 연결, 유전자



프로토타입 (Prototype)

js는 프로토타입을 기반으로 한 객체지향언어

js의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있음
이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메서드를 상속받아 사용할 수 있게 함
이러한 부모 객체를 prototype이라고 함

js의 모든 객체는 [[Prototype]]이라는 인터널 슬롯을 가짐
[[Prototype]]null 또는 객체이며 상속을 구현하는데 사용됨

외부에서 prototype에 접근하려면

  • 객체명.__proto__
  • Object.getPrototypeOf(객체명)
  • 생성자 함수에서는 prototype으로 접근 가능
function Newjeans(name, age) {
   this.name = name;
   this.age = age;
}

const minji = new Newjeans('민지', 20);

console.log(minji.__proto__ === Newjeans.prototype) // true

객체간 상속의 연결 고리는 프로토타입 체인으로 연결 되어 있음



용어 정리

[[Prototype]] 와 prototype 프로퍼티는 다르다
prototype 프로퍼티[[Prototype]]은 모두 프로토타입 객체를 가리키지만 관점의 차이가 있음

[[Prototype]]

  • 모든 객체가 가지고 있는 인터널 슬롯
  • 객체 관점에서는 부모 역할을 하는 프로토타입 객체를 가리킴, 함수객체의 관점에서는 Function.prototype을 가리킴

prototype 프로퍼티

  • 함수 객체만 가지고 있음
  • 생성자함수를 통해 새로 생성될 객체의 부모 역할을 하는 프로토타입을 가리킴

constructor 프로퍼티

프로토타입 객체는 constructor 프로퍼티를 가짐
이 constructor 프로퍼티는 객체의 입장에서 자신을 생성한 객체를 가리킴

prototype chain

js는 특정 객체의 프로퍼티나 메서드에 접근할 때 해당 객체에 없으면 [[Prototype]]이 가리키는 링크를 따라 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메서드를 차례대로 검색함



객체 리터럴 방식으로 생성된 객체의 프로토타입 체인

객체 생성 방법

  • 객체 리터럴
  • 생성자 함수
  • Object( ) 생성자 함수

js엔진이 내부적으로 리터럴 방식을 Obeject( ) 생성자 함수를 통해 생성함
Object( ) 생성자 함수도 함수임으로 prototype 프로퍼티가 있음

Obeject( ) 생성자 함수
: new Obeject( )

즉, 객체 리터럴을 사용하여 객체를 생성하면 그 객체의 프로토타입 객체는 Object.prototype
그래서 toString( ) 같은거 바로 사용가능함



생성자 함수로 생성된 객체의 프로토타입 체인

함수 정의 방식

  • 함수 선언식
  • 함수 표현식
  • Function( ) 생성자 함수

js엔진이 내부적으로 함수 선언식을 함수 표현식으로 바꿔줌

// 변경 전 선언식 모습
function sum(x, y){
   return x + y;
}

//변경 후 표현식 모습
var sum = function sum(x, y){
   return x + y;
}

함수 선언식이든 표현식이든 모두 함수 리터럴 방식을 사용
js엔진이 내부적으로 함수 리터럴 방식을 Function( ) 생성자 함수로 바꿔줌

즉, 함수를 어떻게 정의하든 Function( ) 생성자 함수로 함수 객체가 만들어짐
그래서 모든 함수 객체의 prototype 객체가 Function.prototype
생성자 함수도 함수 객체이므로 생성자 함수의 prototype 객체는 Function.prototype

객체 리터럴 방식이나 생성자 함수 방식이나
결국은 모든 객체의 부모 객체인 Object.prototype 객체에서 프로토타입 체인이 끝



프로토타입 체이닝 제약사항

  1. 순환 참조(circular reference) 허용 X
    ( __proto__를 이용해 닫힌 형태로 다른 객체를 참조하면 에러가 발생)

  2. __proto__의 값은 객체나 null만 가능 (다른 자료형은 무시)

  3. 객체엔 오직 하나의 [[Prototype]]만 있을 수 있음 (두 개의 객체를 상속받지 못 함)


출처

https://poiemaweb.com/js-prototype

profile
인간은 적응의 동물

0개의 댓글

관련 채용 정보