구미구미
디지털 노마드를 꿈꾸며
구미구미
전체 방문자
오늘
어제
  • 분류 전체보기 (28)
    • 알고리즘 (15)
      • 개념정리 (1)
      • 문제풀이 (13)
    • 웹 개발 (11)
      • HTML · CSS (0)
      • JS · TS (3)
      • React · Next.js (6)
      • Node.js (0)
    • TIL (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • nextjs
  • typescript
  • 블록체인
  • javascript
  • 개발
  • I18N
  • 코딩테스트
  • 풀스택
  • 프로그래머스
  • 프론트엔드
  • 이코테
  • 백엔드
  • 리액트
  • react
  • 백준
  • 알고리즘
  • 자바스크립트
  • 파이썬
  • 웹개발 #자바스크립트 #타입스크립트 #JS #TS
  • next.js

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
구미구미

디지털 노마드를 꿈꾸며

웹 개발/JS · TS

자바스크립트와 프로토타입 알아보기

2023. 5. 7. 15:26

들어가며

알고리즘 문제를 풀면서 어떤 객체가 특정 key를 가지는지 확인해야 할 상황이 있었다. 평소 객체가 특정 key를 가지는지 확인하기 위해 in 연산자를 주로 사용했기 때문에 in 연산자를 사용해 문제를 풀었는데, 다른 답안을 참고하던 중 Object.prototype.hasOwnProperty() 메소드를 접하게 되었다.


MDN의 in 연산자에 대한 설명을 보면 in 연산자는 명시된 속성이 명시된 객체에 존재하면 true를 반환합니다.라고 되어있다. hasOwnProperty() 메소드 역시 hasOwnProperty() 메소드는 객체가 특정 프로퍼티를 가지고 있는지를 나타내는 불리언 값을 반환한다.라고 되어 있는데 둘의 차이가 무엇일지 궁금해졌다.


검색해보니 in의 경우 해당 객체의 프로토타입 체인까지 포함한 모든 객체 키를 조회한다고 하고 hasOwnProperty 메소드의 경우 해당 객체가 해당 키를 직접적으로 가지고 있을 경우에만 true 값을 반환한다고 한다. 참고한 글에 의하면 객체의 hasOwnProperty 메소드를 그냥 사용하기보다는 Object.prototype.hasOwnProperty 메소드를 사용할 것을 권장하고 있는데, 해당 객체의 hasOwnProperty 메소드가 재선언되었을 경우를 고려한 것이었다. 이런 내용들을 접하다보니 자바스크립트의 프로토타입 개념과 프로토타입 체인, 재선언 등을 공부하고 정리하는 시간이 필요할 것 같다는 생각이 들어 이 글을 작성하게 되었다.

 

본 포스팅은 Evan Moon님의 [JS 프로토타입] 자바스크립트의 프로토타입 훑어보기와 Toast UI의 프로토타입 기반 언어, 자바스크립트 글을 기반으로 작성되었다. 내용이 정말 자세하기 때문에 두 글들을 꼭 읽어보시라고 말씀드리고 싶다. 👍

 

 

프로토타입과 프로토타입 기반 언어

자바스크립트는 프로토타입 기반의 언어이다.라는 문장을 보면서 고개를 끄덕끄덕하면서도 프로토타입이 정확히 무엇인지는 잘 모르고 있었던 것 같다. 프로토타입을 이해하는 데는 Evan Moon님의 해당 포스팅의 도움을 많이 받았다.
위키피디아에서는 프로토타입 기반 언어를 다음과 같이 정의하고 있다.

프로토타입 기반 언어는 클래스 기반 언어에서 상속을 사용하는 것과는 다르게,
객체를 원형(프로토타입)으로 하는 복제 과정을 통해 객체의 동작 방식을 재사용 할 수 있게 한다.

 

Evan Moon님 포스팅의 프로토타입 패턴 Java 코드 예시를 보면 다음과 같다.

// 이건 너무 객체 생성 비용이 높으니까...
Player evan = new Player();
Player john = new Player();
Player wilson = new Player();

// 이런 방법으로 접근해보는 것은 어떨까?
Player player = new Player();
Player evan = player.clone();
Player john = player.clone();
Player wilson = player.clone();

Player 객체를 딱 한 번 생성하고 그 이후에는 생성된 객체를 복사해서 사용하는 것처럼 자바스크립트와 같은 프로토타입 기반 언어에서도 원형 객체를 복사하는 방식으로 객체를 생성하는 것이다.

 

 

프로토타입 링크

자바스크립트의 경우 string, number, bigint, boolean, undefined, symbol, null의 7가지 원시 타입(Primitive Type)을 제외한 모든 타입은 객체이고, 프로토타입 링크를 통해 원형을 참조하는 식으로 동작한다.

 

다음과 같은 예제를 살펴보자.

function User () {}

const gummy = new User();

console.log(gummy);
console.log(typeof gummy);
User { __proto__: Object }
object

 

 

gummy 객체를 생성하면서 User 함수를 복제한 것이 아니라 User 함수의 프로토타입 객체를 복제했기 때문에 gummy 객체는 function 타입이 아니라 object 타입을 가지게 된다. 이처럼 자바스크립트는 함수를 생성할 때 (위 예에서 User 함수를 생성할 때처럼) 그 함수의 프로토타입 객체를 함께 생성하고 해당 함수의 prototype 프로퍼티에 연결해둔다.

 

function User () {}

console.log(User.prototype);
console.log(typeof User.prototype);
{ constructor: f User(), __proto__: Object }
object

 

브라우저 콘솔에서 실행해보면 다음과 같이 나온다.

 

중요한 것은 new User()라는 문법을 사용해 새로운 객체를 만들게 되면 User 함수 자체가 아니라 User 함수가 생성될 때 함께 생성된 User 함수의 프로토타입 객체를 복제해서 새로운 객체를 만든다는 것! 이때 복제되는 프로토타입 객체를 프로토타입 프로퍼티(Prototype Property)라고 한다.

 

 

constructor 와 __proto__

그렇다면 프로토타입 객체를 콘솔에 찍었을 때 해당 객체가 가지고 있던 프로퍼티인 constructor와 __proto__를 알아보자.

constructor 프로퍼티에는 해당 프로토타입 객체가 생성될 때 선언했던 함수(f User())가 들어있다. 함수를 선언하게 될 때 해당 함수의 프로토타입 객체가 함께 생성되며 이 둘이 연결되게 되는데, 함수는 프로토타입 객체의 constructor 프로퍼티로 연결되고, 프로토타입 객체는 함수의 prototpye 프로퍼티로 연결된다.

아래 내용을 보면 프로토타입 객체와 constructor, __proto__ 프로퍼티의 관계를 이해에 도움이 될 것 같다.

console.log(User.prototype.constructor === User); // true
const gummy = new User();
console.log(gummy.__proto__.constructor === User); // true

gummy.__proto__처럼 생성된 객체가 원본 객체와 __proto__ 프로퍼티를 통해 연결되는 것을 프로토타입 링크(Prototype Link)라고 한다.

function User() {};
const gummy = new User();
console.log(gummy.__proto__ === User.prototype); // true

프로토타입 체인

자바스크립트 내에서 사용되는 모든 객체들은 위와 같은 프로토타입 기반 방식으로 정의되고 생성된다. 우리가 일반적으로 사용하는 빌트인 객체들 역시 같은 방식으로 만들어졌다. 그리고 이 모든 객체들은 Object 함수의 프로토타입인 Object.prototype을 시작으로 복제된다. Object.prototype 객체가 모든 객체의 조상이라는 뜻이다. 따라서 Object.prototype.__proto__을 콘솔에 찍어보면 null이 찍히게 된다.

 

위와 같이 프로토타입으로 이루어진 객체들의 관계를 `프로토타입 체인(Prototype Chain)`이라고 한다.

 

 

마치며

언급했던 Evan Moon님과 Toast UI의 포스팅을 꼭 한 번 읽어보시기 바란다. 잘 작성해주신 두 글을 이해하기 쉽게 정리해보고 싶었으나 잘 되었는지는 모르겠다... 그래도 콘솔 찍을 때마다 보이던 `prototype`, `__proto__`와 조금은 친숙해진 기분이 든다.

 

참고자료

MDN in 연산자 관련 도큐먼트
MDN Object.prototype.hasOwnProperty() 관련 도큐먼트

위키피디아 프로토타입 기반 프로그래밍

'웹 개발 > JS · TS' 카테고리의 다른 글

[번역] 서버 사이드 자바스크립트에 필요한 것  (0) 2023.07.31
[네이버테크톡] '무엇이 TS를 TS답게 하는가' 요약 및 정리  (0) 2022.10.01
    '웹 개발/JS · TS' 카테고리의 다른 글
    • [번역] 서버 사이드 자바스크립트에 필요한 것
    • [네이버테크톡] '무엇이 TS를 TS답게 하는가' 요약 및 정리
    구미구미
    구미구미

    티스토리툴바