- [JavaScript] 프로토타입 이해하기2025년 06월 10일 21시 55분 42초에 업로드 된 글입니다.작성자: DandyNow728x90반응형
JavaScript의 프로토타입 이해하기
JavaScript에서 프로토타입(Prototype)은 객체 지향 프로그래밍의 핵심 개념 중 하나이다. 이는 객체가 다른 객체의 속성과 메서드를 상속받을 수 있도록 하는 메커니즘을 제공한다. 클래스 기반 상속과는 다른, 프로토타입 기반 상속이라는 독특한 방식을 사용한다.
1. 프로토타입의 개념
JavaScript의 모든 객체는
[[Prototype]]이라는 내부 슬롯을 가지며, 이는 다른 객체를 참조한다. 이 참조는 해당 객체의 프로토타입이라고 불린다. 객체에서 특정 속성이나 메서드를 찾을 때, 먼저 자신의 속성을 탐색하고 없으면[[Prototype]]이 가리키는 객체에서 찾는다. 이 과정이 계속 연결되어 프로토타입 체인(Prototype Chain)을 형성한다.__proto__속성: 대부분의 JavaScript 환경에서 객체의[[Prototype]]내부 슬롯은__proto__라는 비표준 속성을 통해 접근할 수 있었다. 하지만 이는 비표준이므로,Object.getPrototypeOf()또는Object.setPrototypeOf()같은 표준 메서드를 사용하는 것이 권장된다.prototype속성: 함수 객체는 특별히prototype이라는 속성을 가진다. 이prototype속성은 함수가 생성자(constructor)로 사용될 때, 해당 함수를 통해 생성된 모든 인스턴스 객체의[[Prototype]]이 될 객체를 가리킨다.- 예시:
// 생성자 함수 // 특징 // 1) `new` 키워드와 함께 호출: 일반 함수와 달리 `new` 연산자와 함께 호출될 때 특별하게 동작한다. // 2) `this` 바인딩: 호출 시 `this`는 새로 생성될 객체를 가리킨다. // 3) 객체 반환:** 명시적으로 `return` 문을 사용하지 않아도, `this`가 가리키는 새로운 객체를 자동으로 반환한다. // 4) 프로토타입 연결: 생성자 함수의 `prototype` 속성에 정의된 메서드나 속성이, 이 생성자 함수로 생성된 모든 인스턴스의 프로토타입 체인에 연결되어 공유된다. function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`안녕하세요, 저는 ${this.name}입니다.`); }; const john = new Person('John'); john.sayHello(); // 안녕하세요, 저는 John입니다. console.log(john.__proto__ === Person.prototype); // true console.log(Person.prototype.constructor === Person); // true위 예시에서
Person함수는 생성자로 사용되었고,Person.prototype객체에sayHello메서드를 추가했다.new Person('John')으로 생성된john객체는Person.prototype을 자신의 프로토타입으로 가지게 되며, 따라서sayHello메서드를 직접 정의하지 않아도 호출할 수 있다.2. 프로토타입을 사용하는 이유
프로토타입은 JavaScript에서 여러 중요한 역할을 수행하며, 다음과 같은 이유로 사용된다.
- 객체 간 상속 및 재사용: 프로토타입을 통해 객체들은 다른 객체의 속성과 메서드를 상속받을 수 있다. 이는 코드의 재사용성을 높이고, DRY(Don't Repeat Yourself) 원칙을 따르는 데 도움을 준다(여러 개의
Person객체를 생성할 때,sayHello메서드를 각 객체마다 복사하는 대신Person.prototype에 한 번만 정의하여 모든 인스턴스가 공유 가능). - 메모리 효율성: 공통된 속성이나 메서드를 각 인스턴스마다 복사하는 대신, 프로토타입 객체에 한 번만 저장하고 여러 인스턴스가 이를 참조하게 함으로써 메모리를 절약할 수 있다. 수많은 객체를 생성할 때 이점은 더욱 커진다.
- 동적인 확장성: 런타임에 프로토타입 객체에 속성이나 메서드를 추가하면, 해당 프로토타입을 상속받는 모든 객체가 즉시 해당 속성이나 메서드를 사용할 수 있게 된다. 이는 객체의 기능을 동적으로 확장하는 데 유용하다.
- 클래스 문법의 기반: ES6에서 도입된
class키워드는 사실 문법적 설탕(syntactic sugar)에 불과하며, 내부적으로는 여전히 프로토타입 기반 상속을 사용한다.class를 이해하기 위해서는 프로토타입에 대한 이해가 필수적이다.
프로토타입은 JavaScript의 객체 지향 특성을 이해하고 활용하는 데 있어 근본적인 개념이다. 이를 통해 유연하고 효율적인 객체 간의 관계를 설정할 수 있다.
3.
Object.create()를 이용한 프로토타입 정의 방법Object.create(proto, [propertiesObject])메서드는 새로운 객체를 생성하고, 이 객체의 프로토타입을 첫 번째 인자로 전달된proto객체로 설정한다. 선택적으로 두 번째 인자로propertiesObject를 전달하여 새로운 객체의 속성들을 정의할 수도 있다.이 방법은 기존의 생성자 함수 방식과 약간 다르게, 특정 객체를 직접적인 프로토타입으로 삼아 새로운 객체를 만들 때 유용하다.
- 기본 사용법 예시:
// 1. 프로토타입이 될 객체를 정의한다. const animalPrototype = { makeSound: function() { console.log("동물이 소리를 낸다."); }, eat: function() { console.log("동물이 음식을 먹는다."); } }; // 2. animalPrototype을 프로토타입으로 하는 새로운 객체를 생성한다. const dog = Object.create(animalPrototype); // 3. 새로운 객체에 고유한 속성을 추가한다. dog.name = "바둑이"; dog.makeSound = function() { // makeSound 메서드를 오버라이드할 수도 있다. console.log("멍멍!"); }; dog.makeSound(); // 멍멍! dog.eat(); // 동물이 음식을 먹는다. console.log(dog.name); // 바둑이 console.log(Object.getPrototypeOf(dog) === animalPrototype); // true이 예시에서
dog객체는animalPrototype을 자신의 프로토타입으로 가지므로,animalPrototype에 정의된eat메서드를 상속받아 사용할 수 있다.makeSound처럼 동일한 이름의 메서드를dog객체 자체에 정의하면, 프로토타입 체인 탐색 규칙에 따라dog객체 자신의makeSound가 호출된다.- 속성 정의와 함께 사용하는 예시:
const personPrototype = { greet: function() { console.log(`Hello, my name is ${this.name}.`); } }; const user1 = Object.create(personPrototype, { name: { value: "Alice", writable: true, enumerable: true, configurable: true }, age: { value: 30, writable: true, enumerable: true, configurable: true } }); user1.greet(); // Hello, my name is Alice. console.log(user1.age); // 30여기서
propertiesObject는Object.defineProperties()에서 사용하는 속성 디스크립터(property descriptor) 형식과 동일하다.4. 왜
Object.create()를 사용할까?클래스/생성자 함수 없이 상속 구현:
Object.create()는 클래스나 생성자 함수를 사용하지 않고도 특정 객체를 프로토타입으로 설정하여 상속 관계를 직접적으로 만들 수 있게 해준다. 이는 "클래스가 없는" 프로토타입 기반 상속의 본질에 더 가깝다고 볼 수 있다.순수한 객체 생성 (null 프로토타입):
Object.create(null)을 사용하면 프로토타입 체인에Object.prototype이 없는, 완전히 순수한 객체를 생성할 수 있다. 이는 특히 해시맵(hash map)처럼 순수하게 키-값 쌍으로만 이루어진 데이터를 다룰 때 유용하며, 예기치 않은 프로토타입 속성(예:toString,hasOwnProperty)과의 충돌을 피할 수 있다.복잡한 상속 구조: 특정 객체의 프로토타입을 동적으로 변경하거나, 다단계 상속 구조를 명시적으로 설정할 때 유연성을 제공한다.
Object.create()는 객체의 프로토타입 체인을 명시적으로 제어하고자 할 때 강력한 도구가 된다. 하지만 일반적으로는 ES6class문법이나 생성자 함수 방식이 더 흔하게 사용되며,Object.create()는 특정 상황이나 고급 패턴에서 활용도가 높다.728x90반응형'언어·프레임워크 > JavaScript' 카테고리의 다른 글
웹 기술(HTML, CSS, JavaScript)로 재탄생한 고전 게임, 테트리스 만들어 보기 (4) 2025.07.05 [JavaScript] 커링 함수 이해하기 (0) 2025.06.10 [JavaScript] 객체 유효성 검사로 Proxy 이해하기 (0) 2025.04.23 [JavaScript] 리플렉트(Reflect) 완벽 정복: JavaScript 메타 프로그래밍의 숨겨진 능력 (1) 2025.04.21 [JavaScript] JavaScript 배열 메서드, 무엇을 바꾸고 무엇을 반환할까? (0) 2025.04.18 다음글이 없습니다.이전글이 없습니다.댓글