19. 프로토타입

Jun_Gyu·2025년 1월 14일
0

한 발자국 더, JS

목록 보기
12/34
post-thumbnail

1. 자바스크립트

객체지향형 언어인 자바스크립트의 특징은 아래와 같다.

  • 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어
  • 객체 기반의 프로그래밍 언어
  • 자바스크립트를 이루고 있는 거의 모든 것이 객체

객체지향 프로그래밍

객체 : 자료구조의 한 종류, 속성을 통해 여러개의 값을 하나의 단어로 구성한 복합적인 자료구조.

즉, 객체는 상태 데이터(property)와 동작(method)을 하나의 논리적인 단위로 묶은 복합적인 자료구조임.


😯 객체지향과 반대되는 의미로는 절차 지향 프로그래밍 이 있으며, 이는 프로그램을 명령어/함수 목록으로 보는 전통적인 명령형 프로그래밍을 의미한다.

독립적인 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임.


또한, 다양한 속성 중에서 프로그램에 필요한 속성만 간추려 내어 표현하는 것을 추상화라고 함



2. 상속 & 프로토타입

자바스크립트는 프로토타입을 기반으로 상속을 구현하고, 불필요한 중복 코드를 제거함.
(기존 코드의 적극적인 재활용)

프로토타입이란?

프로토타입은 어떤 객체의 부모 객체의 역할을 하는 객체이며 다른 객체에 공유 프로퍼티를 제공함.

프로토타입을 상속 받은 자식 객체상위 객체의 프로퍼티를 자신의 프로퍼티처럼 자유롭게 사용 가능.

  • 모든 객체는 [[Prototype]] 이라는 내부 슬롯을 가지고, 여기에 저장되는 프로토타입은 객체 생성 방식에 의해 결정됨.

  • 모든 객체는 하나의 프로토타입을 갖고, 모든 프로토타입은 생성자 함수와 연결되어 있음



3. __proto__ 접근자 프로퍼티

  • 접근자 프로퍼티는 자체적으로 값을 갖지 않고, 다른 데이터 프로퍼티의 값을 읽고나 저장할 때 사용하는 접근자 함수로 구성

모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입이나, [[Prototype]] 내부 슬롯에 간접적으로 접근이 가능하다.

아래는 __proto__ 접근자 프로퍼티의 특징들이다.

  • __proto__ 접근자 프로퍼티는 상속을 통해 사용된다

  • __proto__ 접근자 프로퍼티는 상호 참조에 의해 프로토타입 체인이 생성되는 것을 방지하기 위해 사용

  • __proto__ 접근자 프로퍼티는 코드 내 직접 사용을 권장하지 않는다.
    그 이유는 모든 객체가 __proto__ 접근자 프로퍼티를 사용 할 수 있는것이 아니기 때문이다.

    직접 상속을 통해 Object.prototype 상속 받지 않는 객체 존재함!



4. 함수 객체의 prototype 프로퍼티

함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킴

(생성자 함수로 호출하기 위해 정의하지 않은 일반 함수도 프로퍼티를 소유하지만, 객체를 생성하지 않는 일반함수의 prototype 프로퍼티는 아무런 의미가 없음)

모든 객체가 가지고 있는 __proto__ 접근자 프로퍼티와 함수 객체만이 가지고 있는 prototype 프로퍼티는 동일한 프로토타입을 가리킴.

하지만, 이를 사용하는 주체가 다름.

proto 접근자 프로퍼티의 사용 주체는 모든 객체, prototype 프로퍼티의 사용 주체는 생성자 함수



5. 프로토타입의 constructor 프로퍼티와 생성자 함수

프로토타입과 생성자 함수는 단독으로 존재할 수 없고, 언제나 쌍으로 존재함!
프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성됨

모든 프로토타입은 constructor 프로퍼티를 갖고, 이 프로퍼티는 prototype 프로퍼티로 자신을 참조하고 있는 생성자 함수를 가리킴. 이 연결은 생성자 함수가 생성될 때(함수 객체가 생성될 때) 이루어짐.



6. 프로토타입의 생성 시점

생성자 함수는 사용자가 직접 정의한 사용자 정의 생성자 함수와 자바스크립트가 기본 제공하는 빌트인 생성자 함수로 구분 가능



7. 객체 생성 방식

객체 생성 방식에는 크게 5가지가 존재한다.

  • 객체 리터럴

  • Object 생성자 함수

  • 생성자 함수

  • Object.create 함수

  • ES6의 클래스 문법


이 5가지의 공통점으로는 추상연산 OrdinaryObjectCreate에 의해 생성이 가능하다는 것이다.

* OrdinaryObjectCreate : 필수적으로 자신이 생성할 객체의 프로토타입을 인수로 전달 받고, 옵션으로는 자신이 생성할 객체에 추가할 프로터티 목록 전달 가능), 이 인수는 객체가 생성되는 시점에 객체 생성 방식에 의해 결정



8. 프로토타입 체인

자바스크립트가 객체 지향 프로그래밍의 상속을 구현하는 메커니즘이다.

객체의 프로퍼티/메서드에 접근하려고 할 때
해당 객체에 접근하려는 프로퍼티가 없다면 내부 슬롯의 참조를 따라
자신의 부모역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색하는 것을 말함.

프로토타입 체인의 최상위 객체는 언제나 Object.prototype이다.

따라서, 모든 객체는 Object.prototype을 상속받고 Object.prototype이 프로토타입 체인의 최상단이자 종점이라고 할 수 있음.

만약 Object.prototype에서 프로퍼티 검색 할 수 없는 경우에는 undefined를 반환함.



9. 프로퍼티 섀도잉

프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면 덮어쓰는 것이 아니라, 인스턴스 프로퍼티로 추가하고 상속 관계에 의해 프로퍼티가 가려지는 현상

  • 프로토타입이 소유한 프로퍼티프로토타입 프로퍼티라고 하며, 인스턴스가 소유한 프로퍼티인스턴스 프로퍼티라고 함.

  • 프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면 프로토타입 프로퍼티를 덮어쓰는 것이 아닌 인스턴스 프로퍼티로 추가되며, 상속 관계에 의해서 프로퍼티가 가려지게 됨.



10. instanceof 연산자

이항 연산자로, 좌변의 객체를 가리키는 식별자,
그리고 우변의 생성자 함수를 가리키는 식별자를 피연산자로 받음



11. 정적 프로퍼티/메서드

생성자 함수로 인스턴스를 생성하지 않아도 참조/호출 가능한 프로퍼티/메서드

생성자 함수가 생성한 인스턴스로 참조 또는 호출이 불가하며,

정적 프로퍼티 or 메서드는 인스턴스의 프로토타입 체인에 속한 객체의 프로퍼티 or 메서드가 아니다.



12. 프로퍼티 존재 확인

객체 내에 특정 프로퍼티의 존재 여부를 확인.

확인 대상 객체의 프로퍼티뿐만 아니라 확인 대상 객체가 상속받는 모든 프로토타입의 프로퍼티를 확인함.

  • in 연산자 :
    확인 대상 객체의 프로퍼티 뿐만 아니라, 확인 대상 객체가 상속받은 모든 프로토타입의 프로퍼티를 확인하기에 주의가 필요함.

  • Reflext.has 메서드 :
    ES6에서 도입되었으며, in 연산자와 동일하게 동작함.

  • Object.prototype.hasOwnProperty 메서드 :
    인수로 전달받은 프로퍼티 키가 객체 고유의 프로퍼티 키인 경우 true를 반환하고, 상속받은 프로토타입의 프로퍼티 키인 경우 false를 반환



13. 프로퍼티 열거

프로퍼티 열거에는 아래의 두가지 종류가 있다.

for ... in 문

객체 프로토타입 체인 상에 존재하는 모든 프로토타입의 프로퍼티 중

프로퍼티 어트리뷰트 [[Enumerable]]이 true인 프로퍼티를 순회하며 열거함.

즉, 객체의 프로퍼티 개수만큼 순회하며,

순서를 보장하지 않는다.



Object. keys/values/entries 메서드

객체 자신의 고유 프로퍼티만 열거한다.



profile
시작은 미약하지만, 그 끝은 창대하리라

0개의 댓글