LogoSEO Jing
  • All Posts
  • SEO Jing
  • okayJing
  • KD Team
  • CLAB Coreteam
  • Study

Contact Me

© 2026 SEOJing. All rights reserved.

자바스크립트 퀴즈북 리마인드 Day 11: class를 봐도 프로토타입을 읽는다

2026년 7월 6일·5분 읽기
오늘의 질문: “class로 만들었으니 자바나 타입스크립트의 class처럼만 읽으면 될까?”

먼저 보는 코드

js
class UserCard {
  constructor(user) {
    this.user = user;
  }

  render() {
    return `<article>${this.user.name}</article>`;
  }
}

const card = new UserCard({ name: "Jin" });

겉으로는 익숙한 class입니다. 하지만 자바스크립트에서 render는 각 인스턴스 안에 복사되는 함수가 아니라 UserCard.prototype에 놓이는 메서드입니다. card.render()를 호출하면 엔진은 먼저 card 자신의 프로퍼티를 보고, 없으면 프로토타입 체인을 따라 올라가서 render를 찾습니다.

프로토타입 조회 경로

틀리기 쉬운 직감: class가 prototype을 숨겨 준다

class 문법은 prototype을 없애지 않습니다. 더 읽기 쉬운 문법으로 감싼 것입니다.

js
class ButtonView {
  click() {
    return "clicked";
  }
}

const view = new ButtonView();

Object.hasOwn(view, "click"); // false
Object.hasOwn(ButtonView.prototype, "click"); // true

리뷰할 때 이 차이가 중요한 이유는 메서드 위치가 동작과 성능에 영향을 주기 때문입니다. prototype 메서드는 인스턴스들이 공유합니다. 반대로 constructor 안에서 함수를 매번 만들면 인스턴스마다 새 함수가 생깁니다.

js
class ItemRow {
  constructor(item) {
    this.item = item;
    this.render = () => `<li>${this.item.title}</li>`;
  }
}

이런 코드가 항상 틀린 것은 아닙니다. arrow function 필드나 constructor 바인딩은 this 문제를 줄이는 데 쓰이기도 합니다. 다만 “왜 공유 메서드가 아니라 인스턴스별 함수여야 하는가?”를 설명할 수 있어야 합니다.

프로퍼티 조회는 가까운 곳부터 본다

프로토타입 체인은 상속이라기보다 조회 경로로 읽는 편이 안전합니다.

js
const base = {
  role: "guest",
  canEdit() {
    return false;
  },
};

const user = Object.create(base);
user.name = "Jin";
user.role = "admin";

user.role; // "admin"
user.canEdit(); // false

role은 user 자신의 값이 있으므로 거기서 끝납니다. canEdit은 자기 자신에게 없으니 base에서 찾습니다. 같은 이름의 프로퍼티가 더 가까운 객체에 있으면 위쪽 값은 가려집니다.

프론트엔드에서는 이 감각이 테스트 mock, 라이브러리 객체 확장, class 상속 디버깅에서 필요합니다. 어떤 값이 “원래 객체에 있는 값”인지, “prototype에서 올라온 값”인지 구분하지 못하면 원인을 잘못 짚습니다.

상속보다 합성이 더 읽기 쉬울 때가 많다

자바스크립트 class 상속은 쓸 수 있지만, UI 코드에서 깊은 상속 구조는 리뷰 비용을 키웁니다.

js
class TrackingButton extends Button {
  click() {
    analytics.track("button_click");
    return super.click();
  }
}

이 코드를 보려면 TrackingButton.click, Button.click, 그리고 super 호출 순서를 함께 봐야 합니다. 간단한 확장은 괜찮지만, 상태·렌더링·네트워크·분석 이벤트가 상속 계층에 흩어지면 변경 영향이 흐려집니다.

많은 프론트엔드 코드에서는 합성이 더 선명합니다.

js
function createTrackingButton(button, analytics) {
  return {
    click() {
      analytics.track("button_click");
      return button.click();
    },
  };
}

합성이 항상 정답이라는 뜻은 아닙니다. 다만 리뷰 질문은 명확해집니다.

이 동작은 “is-a” 관계로 묶어야 하나, 아니면 기존 객체에 기능을 덧붙이는 편이 충분한가?

instance field와 prototype method를 구분한다

요즘 문법에서는 class field도 자주 보입니다.

js
class SearchBox {
  query = "";

  onChange = (event) => {
    this.query = event.target.value;
  };

  reset() {
    this.query = "";
  }
}

query와 onChange는 인스턴스마다 생깁니다. reset은 prototype에 놓입니다. onChange를 arrow field로 만들면 callback으로 넘겨도 this가 덜 흔들립니다. 대신 인스턴스마다 함수가 만들어진다는 비용이 있습니다.

그래서 코드 리뷰에서는 이렇게 봅니다.

코드 모양좋은 이유확인할 점
prototype method인스턴스들이 메서드를 공유함callback으로 빼도 this가 안전한가?
arrow field methodthis가 lexical하게 고정됨인스턴스마다 함수가 필요한가?
extends/super기존 구현을 재사용함호출 순서와 부수 효과가 숨어 있지 않은가?
Object.create명시적 prototype 연결소유 프로퍼티와 상속 프로퍼티를 구분하는가?

프론트엔드 코드 리뷰 체크리스트

obj.method가 자기 자신의 프로퍼티인지 prototype에서 온 것인지 확인했는가? class 메서드, class field, constructor 바인딩이 각각 왜 선택됐는지 설명할 수 있는가? 상속 계층이 UI 상태·부수 효과·렌더링을 너무 멀리 흩어 놓지 않는가? super 호출 전후에 부수 효과 순서가 중요하지 않은가? 테스트 mock이 prototype 메서드를 바꿔야 하는지, 인스턴스 프로퍼티를 바꿔야 하는지 구분했는가? 라이브러리 객체나 전역 prototype을 수정하는 위험한 패턴이 없는가?

class를 보더라도 핵심은 “객체가 어떤 설계 철학을 따르는가”가 아닙니다. 런타임에서 프로퍼티를 어디서 찾고, 메서드가 어디에 놓이며, 변경 영향이 어느 객체까지 퍼지는지를 읽는 것입니다.

Day 11 복습 퀴즈

Quiz1 / 4
Q.다음 코드에서 click 메서드는 어디에 있을까요?
js
"class Button {\n  click() { return 'ok';

Post Q&A

오케이징에게 물어보기

자바스크립트 퀴즈북 리마인드 Day 11: class를 봐도 프로토타입을 읽는다 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!

0/500

포스트 목록

/study/javascript-quizbook
파일 11개, 폴더 0개
자바스크립트 퀴즈북 리마인드 Day 1: 숫자는 왜 가끔 믿을 수 없을까자바스크립트 퀴즈북 리마인드 Day 2: 같은 값인지 묻는 네 가지 방법자바스크립트 퀴즈북 리마인드 Day 3: + 연산자와 ToPrimitive 흐름자바스크립트 퀴즈북 리마인드 Day 4: 프로퍼티 descriptor와 freeze의 경계자바스크립트 퀴즈북 리마인드 Day 5: 참조, 복사, Map/Set의 메모리 감각자바스크립트 퀴즈북 리마인드 Day 6: 스코프 체인과 호이스팅자바스크립트 퀴즈북 리마인드 Day 7: 클로저 버그와 오래된 값자바스크립트 퀴즈북 리마인드 Day 8: 이벤트 루프와 Promise 타이밍자바스크립트 퀴즈북 리마인드 Day 9: this는 호출한 쪽이 정한다자바스크립트 퀴즈북 리마인드 Day 10: 함수는 값이고 경계다자바스크립트 퀴즈북 리마인드 Day 11: class를 봐도 프로토타입을 읽는다

같은 섹션의 대표 이미지

11 posts · latest first
인스턴스에서 프로토타입과 Object.prototype으로 이어지는 프로퍼티 조회 경로 다이어그램
Study26. 07. 07.

자바스크립트 퀴즈북 리마인드 Day 11: class를 봐도.

프로토타입 조회, class 문법, 인스턴스 필드와 prototype 메서드 차이를 프론트엔드 코드 리뷰 관점에서 정리합니다.

26. 07. 07.SEOJing
입력, 순수 계산, 출력, 부수 효과 경계를 나누어 함수 설계를 보여주는 다이어그램
Study26. 07. 06.

자바스크립트 퀴즈북 리마인드 Day 10: 함수는 값이고 경계다.

고차 함수, 순수 함수, 부수 효과, async 함수의 Promise 반환을 코드 리뷰에서 어떻게 읽을지 정리합니다.

26. 07. 06.SEOJing
메서드 호출, 분리된 함수, 이벤트 콜백, bind와 arrow function의 this 차이를 보여주는 다이어그램
Study26. 07. 05.

자바스크립트 퀴즈북 리마인드 Day 9: this는 호출한 쪽이.

this 바인딩을 정의 위치가 아니라 호출 형태, 메서드 분리, arrow function, bind 기준으로 읽는 방법을 코드 리뷰 관점에서 정리합니다.

26. 07. 05.SEOJing
콜 스택이 비워진 뒤 마이크로태스크 큐가 먼저 실행되고 다음 태스크로 넘어가는 이벤트 루프 다이어그램
Study26. 07. 04.

자바스크립트 퀴즈북 리마인드 Day 8: 이벤트 루프와.

콜 스택, 태스크 큐, 마이크로태스크 큐를 기준으로 Promise와 setTimeout 실행 순서를 코드 리뷰 관점에서 정리합니다.

26. 07. 04.SEOJing
클로저가 생성 위치의 바인딩을 기억해 나중 실행에서 오래된 값을 읽을 수 있음을 보여주는 다이어그램
Study26. 06. 29.

자바스크립트 퀴즈북 리마인드 Day 7: 클로저 버그와 오래된.

클로저가 값 복사가 아니라 렉시컬 환경 참조라는 점을 stale closure, 루프 콜백, React 이벤트 리뷰 관점에서 정리합니다.

26. 06. 29.SEOJing
스코프 체인과 호이스팅 관계를 단순화한 다이어그램
Study26. 06. 28.

자바스크립트 퀴즈북 리마인드 Day 6: 스코프 체인과 호이스팅.

스코프 체인, 클로저, var/let/const 호이스팅 차이를 콜백·상태 버그 리뷰 관점에서 짧게 정리합니다.

26. 06. 28.SEOJing
JavaScript 객체 참조와 Map, Set, WeakMap의 참조 구조를 비교한 다이어그램
Study26. 06. 27.

자바스크립트 퀴즈북 리마인드 Day 5: 참조, 복사,.

객체 참조와 얕은 복사, Object와 Map/Set의 차이, WeakMap/WeakSet이 필요한 메모리 상황을 프론트엔드 코드 리뷰 관점에서 정리합니다.

26. 06. 27.SEOJing
JavaScript 프로퍼티 descriptor가 data descriptor와 accessor descriptor로 갈라지는 구조 다이어그램
Study26. 06. 26.

자바스크립트 퀴즈북 리마인드 Day 4: 프로퍼티.

객체 프로퍼티를 key/value가 아니라 descriptor로 읽는 법, getter/setter와 defineProperty, preventExtensions/seal/freeze의 경계를 코드 리뷰 관점에서 정리합니다.

26. 06. 26.SEOJing
객체가 ToPrimitive를 거쳐 + 연산자의 문자열 연결 또는 숫자 덧셈으로 갈라지는 흐름 다이어그램
Study26. 06. 25.

자바스크립트 퀴즈북 리마인드 Day 3: + 연산자와.

객체가 원시값으로 바뀌는 ToPrimitive 흐름, + 연산자의 문자열 연결과 숫자 덧셈 분기, Symbol.toPrimitive가 코드 리뷰에서 왜 중요한지 정리합니다.

26. 06. 25.SEOJing
==, ===, Object.is, SameValueZero의 차이를 정리한 JavaScript equality 다이어그램
Study26. 06. 24.

자바스크립트 퀴즈북 리마인드 Day 2: 같은 값인지 묻는 네.

==, ===, Object.is, SameValueZero가 각각 어떤 비교 알고리즘을 쓰는지 정리하고, includes와 indexOf, Map/Set 키 비교에서 생기는 프론트엔드 리뷰 포인트를 잡습니다.

26. 06. 24.SEOJing
JavaScript Number, safe integer, NaN, -0, BigInt를 한 장으로 정리한 다이어그램
Study26. 06. 23.

자바스크립트 퀴즈북 리마인드 Day 1: 숫자는 왜 가끔 믿을.

자바스크립트의 Number가 왜 정수처럼 보여도 부동소수점 모델 위에서 움직이는지, NaN과 -0, safe integer, BigInt를 프론트엔드 코드 리뷰 관점에서 다시 정리합니다.

26. 06. 23.SEOJing