블로그로 돌아가기
Javascript

javascript prototype 이해: 개념부터 실무 적용까지 한 번에

javascript prototype 이해를 통해 프로토타입 체인, 객체 생성 패턴, 성능·보안 이슈를 실무 예제와 체크리스트로 바로 적용할 수 있도록 정리합니다. 실무 적용 흐름과 자주 하는 실수까지 함께 확인할 수 있습니다.

프로토타입객체지향-자바스크립트상속-패턴ES6-클래스-비교
javascript prototype 이해를 설명하는 다이어그램을 포함한 기술 블로그 썸네일

javascript prototype 이해이 필요한 상황

javascript prototype 이해는 객체의 상속 구조를 정확히 파악하고 메서드 공유, 메모리 최적화, 디버깅을 효율화하려는 실무 개발자에게 필수입니다. 이 글에서는 prototype의 개념, 프로토타입 체인 동작, ES6 클래스와의 차이, 실제 코드 예제와 적용 시 주의점까지 빠르게 적용할 수 있도록 정리합니다.

javascript prototype 이해 핵심 개념

프로토타입은 자바스크립트 객체가 다른 객체의 속성과 메서드를 참조할 수 있게 하는 메커니즘입니다. 모든 객체는 내부 슬롯 [[Prototype]](일반적으로 proto)을 가지며, 속성 접근 시 해당 체인을 따라 올라가며 값을 찾습니다. 이 섹션에서는 생성자 함수, Object.create, 그리고 ES6 클래스가 어떻게 프로토타입을 사용하는지 설명합니다.

  • 생성자 함수: 함수의 prototype 프로퍼티에 메서드를 추가하면 모든 인스턴스가 공유합니다.
  • Object.create: 명시적으로 특정 프로토타입을 갖는 객체를 만듭니다.
  • 클래스 문법: 문법적 설탕으로 내부적으로는 프로토타입을 사용합니다.

javascript prototype 이해 실무 예제

다음 예제는 생성자 함수와 Object.create, 클래스 방식의 차이를 보여줍니다.

// 생성자 함수 + prototype function User(name) { this.name = name; } User.prototype.say = function() { return `hi ${this.name}`; }; const a = new User('Alice'); console.log(a.say()); // hi Alice // Object.create const proto = { greet() { return `hello ${this.name}`; } }; const b = Object.create(proto); b.name = 'Bob'; console.log(b.greet()); // hello Bob // ES6 class (프로토타입 기반) class Person { constructor(name) { this.name = name; } shout() { return this.name.toUpperCase(); } } const c = new Person('Carol'); console.log(c.shout()); // CAROL

위 예제에서 중요한 점은 메서드가 인스턴스마다 복사되지 않고 프로토타입 객체에 한 번만 존재한다는 점입니다. 이는 메모리 사용과 성능 측면에서 유리합니다.

언제 쓰면 좋고 언제 피해야 할까

언제 쓰면 좋은가:

  • 메서드 공유로 인스턴스별 메모리 절약이 필요할 때
  • 런타임에 객체 관계를 동적으로 구성해야 할 때 (Object.create)
  • 프로토타입 체인 기반 라이브러리/플러그인 확장 시

언제 피해야 하는가:

  • 단순한 데이터 구조(POJO)나 상태 관리 용도로 복잡한 프로토타입 체인을 도입할 필요가 없을 때
  • 예상치 못한 프로퍼티 오버라이드가 위험할 때(보안/무결성 문제)
  • 성능 병목이 프로토타입 체인 탐색 때문이라고 판단되는 경우, 단순화 필요

프로토타입 관련 비교표

구분항목1항목2항목3
내용생성자 함수Object.createES6 class
내용메서드 공유(프로토타입)명시적 프로토타입 지정문법적 설탕, 내부는 프로토타입
내용new 키워드 필요단순 객체 상속 구조가독성↑, 동작은 동일

실무 체크리스트

  • 인스턴스 메서드가 불필요하게 복사되는지 확인
  • Object.prototype 오버라이딩 위험성 검토
  • 프로토타입 체인 깊이로 인한 성능 영향 측정(핫 루프에서의 속성 접근)
  • 외부 라이브러리와의 프로토타입 충돌 여부 확인
  • 필요 시 Object.create로 명시적 프로토타입 사용 고려

성능·보안·운영 주의점

성능:

  • 프로토타입 체인이 깊을수록 속성 접근 비용이 증가합니다. 빈번한 속성 접근이 있는 경로는 캐시하거나 직접 소유 속성으로 복사하는 것을 고려하세요.

보안/무결성:

  • Object.prototype에 값을 추가하면 모든 객체가 영향을 받습니다. 글로벌 확장은 금지하세요.
  • 프로토타입 오염(Prototype Pollution) 공격에 유의: 외부 입력을 직접 객체 키로 사용하여 프로토타입을 수정하지 마세요.

운영/디버깅:

  • 디버깅 시 __proto__를 확인하면 객체 상속 구조를 빠르게 파악할 수 있습니다.
  • 소스 코드에서 클래스 문법과 프로토타입 방식이 혼재하면 가독성 저하가 발생합니다. 팀 규칙으로 통일하세요.

javascript prototype 이해 적용 팁 및 체크 예제

실무에서 흔히 쓰이는 패턴: 메서드를 프로토타입에 두고 인스턴스에는 상태만 유지합니다.

function Cache() { this.store = Object.create(null); // 프로토타입 오염 방지 } Cache.prototype.set = function(key, value) { this.store[key] = value; }; Cache.prototype.get = function(key) { return this.store[key]; }; const cache = new Cache(); cache.set('x', 1); console.log(cache.get('x'));

위 예제에서 Object.create(null)을 사용하면 store가 프로토타입 체인을 갖지 않아 키 충돌/오염 위험을 줄일 수 있습니다.

자주 묻는 질문

Q1: 프로토타입과 클래스는 어떤 차이가 있나요? A1: ES6 클래스는 문법적 설탕입니다. 내부 동작은 여전히 프로토타입 기반으로 메서드를 프로토타입 객체에 저장합니다. 다만 클래스는 가독성과 상속 문법을 명확히 해줍니다.

Q2: 프로토타입 체인이 성능에 큰 영향을 주나요? A2: 대부분의 경우 큰 영향은 없지만, 매우 빈번한 속성 접근(핫 루프)이나 깊은 체인이 있는 경우 비용이 누적될 수 있으므로 프로파일링이 필요합니다.

Q3: 프로토타입 오염이란 무엇이며 어떻게 방지하나요? A3: 외부 입력이 객체 키로 사용되어 Object.prototype 등에 악의적 속성을 추가하는 공격입니다. 입력 검증, Object.create(null) 사용, 외부 라이브러리의 안전성 검토로 방지합니다.

Q4: 언제 Object.create를 써야 하나요? A4: 명시적으로 특정 프로토타입을 설정하거나, 프로토타입 오염을 피하기 위해 프로토타입이 없는 객체를 만들고 싶을 때 유용합니다.

정리

  • javascript prototype 이해는 메서드 공유와 상속 모델을 명확히 하여 메모리와 유지보수 이점을 줍니다.
  • 생성자 함수, Object.create, ES6 클래스는 내부적으로 프로토타입을 사용하지만 목적과 가독성이 다릅니다.
  • 프로토타입 오염과 깊은 체인으로 인한 성능 문제를 반드시 점검하세요.
  • 실무 체크리스트로 코드 리뷰와 프로파일링을 병행하면 안전합니다.