이 영역을 누르면 첫 페이지로 이동
Nuhends 의 Tech Life 블로그의 첫 페이지로 이동

Nuhends 의 Tech Life

페이지 맨 위로 올라가기

Nuhends 의 Tech Life

IT / Tech / 재테크 관련 뉴스를 최대한 알기 쉽게 전달하는 Tech 블로그 입니다.

[JS] 문법정리 > 확실한 프로토타입 체이닝 정리

  • 2020.12.29 17:53
  • 프로그래밍/JAVASCRIPT 사전
반응형

[JS] 문법정리 > 확실한 프로토타입 체이닝 정리

JS 문법정리 > 프로토타입 체이닝


 

'자바스크립트'는 기존 C++ 이나 자바 같은 객체지향 프로그래밍 언어와는 다른

프로토타입 기반의 객체지향 프로그래밍을 지원한다.

 

즉, 프로토타입(prototype) 에 대해 잘 이해하고 있어야, 자바스크립트의 동작 과정을 제대로 이해할 수 있다.

 

이번 포스팅의 결론이자 규칙을 먼저 기억하자.

📌규칙

JS에서 "모든 객체" 는
자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를
자신의 프로토타입 객체(부모 객체)로 취급한다.

 

예제

function Factory(name) {
    this.name = name;
}

// box 객체 생성
var box = new Factory('box');

console.dir(Factory);
console.log(box);

 

예제 코드의 관계도를 그림으로 표현해보면 다음과 같다.

 

생성자 함수, 생성 객체, prototype 객체 도식도

 

앞서 살펴본 규칙대로, 자바스크립트의 모든 객체는
자신의 부모의 프로토타입 객체를 가리키는 참조 링크 형태의 숨겨진 프로퍼티가 있다.

이 링크를 암묵적 프로토타입 링크(implicit prototype link) 라고 부르고, 
자신의 [[prototype]] 프로퍼티에 저장한다.

 

이 예제에 적용해보면

"생성자 함수 Factory 의 prototype 프로퍼티" 와 "자식인 box 객체의 [[prototype]] 프로퍼티" 가 같은 객체를 가리킨다.

 

즉, 자바스크립트에서 객체를 생성하는 건 생성자 함수의 역할이지만, 

생성된 객체의 실제 부모 역할을 하는 건 

생성자 자신이 아닌 생성자의 prototype 프로퍼티가 가리키는 프로토타입 객체이다

 

📌참고
이 숨겨진 링크는 ECMAScript에서는 [[prototype]] 프로퍼티로 정하고 내부적으로만 사용된다고 명시하고 있다.
하지만 크롬, 파이어폭스에서는 __proto__ 프로퍼티로 명시적으로 제공하고 있다.

즉, __proto__ 프로퍼티 와 [[prototype]] 프로퍼티는 같다고 간주하면 된다.

→ __proto__=== [[prototype]]   // true

1. 객체 리터럴 방식에서의 프로토타입 체이닝

자바스크립트에서는 객체에 접근하려는 프로퍼티가 없을 경우, 

자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티에도 접근이 가능하다. 

이것이 프로토타입 체이닝 개념이다.

 

var obj = {
    name: 'child',
    sayName: function() {
        console.log('name : ' + this.name);
    }
};

obj.sayName();         // 'child'
obj.sayAge();         // Uncaught TypeError
console.log(obj.hasOwnProperty('name'));   // true
console.log(obj.hasOwnProperty('age'));    // false

리터럴 방식으로 obj 객체에는 sayAge 라는 프로퍼티를 가지고 있지 않다.

그렇기 때문에 "Uncaught TypeError" 에러가 발생한다.

 

이와 마찬가지로 hasOwnProperty 라는 프로퍼티도 가지고 있지 않다.

 

그런데 에러가 발생하지 않았다. 어떻게 된 일인가?!

혼란..

 

이를 이해하려면

객체 리터럴 방식으로 객체를 생성할 때 동작 원리와 프로토타입 체이닝

 

이 두가지 개념을 살펴보아야 한다.

 


 

1. 객체 리터럴 방식의 동작 과정

a. 객체 리터럴 방식으로 생성한 객체는 사실 Object() 라는 내장 생성자 함수로 생성 된다. 
b. Object() 생성자 함수도 함수 객체이므로, prototype 이라는 프로퍼티 속성이 있다.

 

따라서, 이전 예제처럼 아래와 같이 도식도를 그릴수 있다.

 

객체 리터럴 방식으로 선언된 객체의 프로토타입 체이닝 도식도

 

"객체 리터럴 방식"으로 생성한 obj 객체는

Object 함수의 prototype 프로퍼티가 가리키는 Object.prototype 객체를

자신의 [[proto]] 프로퍼티 로 연결(히든 링크!!) 한다.

 

2. 프로토타입 체이닝

obj.hasOwnProperty 와 같이

객체에 없는 프로퍼티에 접근하려고 할 때 

 

히든링크인 [[prototype]] 링크를 따라 

자신의 부모 역할을 하는 프로토타입 객체(Object.prototype)에서

프로퍼티를 차례대로 검색하는 것을 "프로토타입 체이닝" 이라고 한다.

 

위의 예제에서는 obj.hasOwnProperty 를 obj 에서 찾는데 실패하였기 때문에, 

프로토타입 체이닝이 발생하여, 히든링크를 타고 올라가 프로토타입 객체에서 해당 프로퍼티를 발견했다.

 

📌참고
Object.prototype 객체는 자바스크립트 모든 객체의 조상 역할을 하는 객체로,
toString(), hasOwnProperty() 등과 같은 표준 메서드를 제공한다.

이는 ECMAScript 에 명세되어있다.

 

2. 생성자 함수로 생성된 객체의 프로토타입 체이닝

"생성자 함수로 생성된 객체"는

앞서 살펴본 객체 리터럴 방식으로 생성된 객체와 약간 다른 프로토타입 체이닝이 이루어진다.

 

하지만, 기본 규칙은 변하지 않는다.

📌규칙
JS에서 모든 객체는 
자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를 
자신의 프로토타입 객체(부모 객체)로 취급한다.

예제를 통해 살펴보자.

// Factory() 생성자 함수
function Factory(name, number) {
    this.name = name;
    this.number = number;
}

// box 객체 생성
var box = new Factory('box', 30);

// 프로토타입 체이닝
console.log(box.hasOwnProperty('name'));

// Factory.prototype 객체 출력
console.dir(Factory.prototype);

생성자 함수로 생성된 객체의 프로토타입 체이닝 도식도

 

앞서 살펴본 것처럼, box 객체의 [[prototype]] 객체는

Factory 생성자 함수 객체의 prototype 프로퍼티가 가리키는 객체(Factory.prototype) 과 동일하다.

 

여기서 프로토타입 체이닝 일어나는 단계는 다음과 같다.

1. box.hasOwnProperty() 메서드를 호출했지만, box 객체 에는 해당 프로퍼티가 없었다.

2. 첫 번째 프로토타입 체이닝이 발생
    Factory.prototype 객체에서 hasOwnProperty() 메서드를 찾는다.
    그러나 constructor 프로퍼티만 가질 뿐 해당 프로퍼티가 없다.
    Factory.prototype 프로퍼티 역시 객체이므로 [[prototype]] 라는 히든 링크를 가지고 있다. 

3. 두번째 프로토타입 체이닝 발생
    모든 객체는 Object.prototype 을 프로토타입 객체로 가진다.
    이 객체에서 hasOwnProperty() 메서드를 찾아서 참조하게 된다.

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'프로그래밍 > JAVASCRIPT 사전' 카테고리의 다른 글

[JS] 화살표 함수, 쉽고 빠르게 정리하기  (8) 2021.05.11
[YOU DON'T KNOW JS 정리] THIS (1)  (4) 2021.05.08
[JS] arguments 객체 그리고 유사배열 객체  (0) 2021.05.05
[JS] 문법 정리 > 함수: 선언, 호이스팅, 일급 객체  (0) 2020.12.20
[JS] 문법정리 > 타입과 변수  (0) 2020.12.09

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [YOU DON'T KNOW JS 정리] THIS (1)

    [YOU DON'T KNOW JS 정리] THIS (1)

    2021.05.08
  • [JS] arguments 객체 그리고 유사배열 객체

    [JS] arguments 객체 그리고 유사배열 객체

    2021.05.05
  • [JS] 문법 정리 > 함수: 선언, 호이스팅, 일급 객체

    [JS] 문법 정리 > 함수: 선언, 호이스팅, 일급 객체

    2020.12.20
  • [JS] 문법정리 > 타입과 변수

    [JS] 문법정리 > 타입과 변수

    2020.12.09
다른 글 더 둘러보기

정보

Nuhends 의 Tech Life 블로그의 첫 페이지로 이동

Nuhends 의 Tech Life

  • Nuhends 의 Tech Life의 첫 페이지로 이동
반응형

검색

메뉴

  • 홈
  • 웹 개발
  • 경제 데이터
  • 경제 공부
  • 방명록

카테고리

  • 분류 전체보기 (127)
    • 프로그래밍 (69)
      • React (3)
      • HTML&CSS 사전 (13)
      • JAVASCRIPT 사전 (11)
      • Algorithm (23)
      • 이슈 정리 (2)
      • 개발 환경 (4)
      • NodeJS (1)
      • Typescript (4)
      • NextJS (5)
      • React-Query (2)
      • ai (1)
    • 경제 데이터 (22)
      • 주식 순위 (20)
      • 경제지표 (2)
    • 경제 공부 (25)
      • 경제 신문 읽기 (3)
      • 세금 재테크 (7)
      • 인사이트 (4)
      • 경제용어정리 (9)
      • 정부 지원 제도 관련 (2)
    • 팁 모음 (11)
      • 인터넷 (5)
      • 생활 (3)
      • SNS 맛집 (3)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 코딩테스트
  • softeer
  • 코테 풀이
  • 코테
  • 자바스크립트
  • javascript
  • 프로그래머스
  • 알고리즘

나의 외부 링크

정보

nuhends의 Nuhends 의 Tech Life

Nuhends 의 Tech Life

nuhends

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © nuhends. Designed by Fraccino.

티스토리툴바