javascirpt prototype이란 무엇인가? 한 번 쓰면 멈출 수 없다

작성일 :

JavaScript Prototype이란 무엇인가? 한 번 쓰면 멈출 수 없다

JavaScript는 객체 지향 프로그래밍 패러다임을 지원하는 언어입니다. 그 중에서도 프로토타입(prototype)은 JavaScript의 객체 지향 기능을 이해하는 데 중요한 개념입니다. 프로토타입의 개념을 잘 이해하게 되면, 더 효과적으로 JavaScript 코드를 작성할 수 있습니다. 이 글에서는 JavaScript에서 프로토타입이 어떻게 작동하는지, 왜 중요한지를 심도 있게 다룹니다.

프로토타입의 기본 개념

JavaScript의 모든 객체는 다른 객체로부터 상속을 받습니다. 이 상속을 가능하게 하는 구조가 바로 프로토타입(prototype)입니다. 간단히 말해, 프로토타입은 객체의 부모 객체로 간주될 수 있습니다. 다음과 같은 예제를 통해 이해해 보겠습니다:

javascript
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.greet = function() {
  return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
};

const alice = new Person('Alice', 30);
console.log(alice.greet()); // Hello, my name is Alice and I am 30 years old.

위 예제에서 Person 생성자 함수와, 이 생성자 함수의 인스턴스 alice를 봅시다. Person.prototype.greet 메소드는 alice 객체가 직접 소유한 프로퍼티는 아니지만, alicePerson.prototype에 정의된 메서드인 greet를 호출할 수 있습니다. 이는 alicePerson 생성자 함수의 인스턴스로서 그 프로토타입 체인을 통해 greet 메서드를 상속받았기 때문입니다.

프로토타입 체인

JavaScript에서 객체는 모두 다른 객체로부터 프로퍼티와 메서드를 상속받습니다. 이 상속 관계를 프로토타입 체인(prototype chain)이라고 부릅니다. 프로토타입 체인은 객체의 프로토타입이 또 다른 객체의 프로토타입으로 이어지는 구조를 의미합니다. 다음 예제를 보시면 더 명확히 이해할 수 있습니다:

javascript
function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  return `${this.name} makes a sound.`;
};

function Dog(name) {
  Animal.call(this, name); // Super constructor
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.bark = function() {
  return `${this.name} barks.`;
};

const max = new Dog('Max');
console.log(max.speak()); // Max makes a sound.
console.log(max.bark()); // Max barks.

위 예제에서 Dog 객체는 Animal 객체를 하위 클래스처럼 확장하고 있습니다. 이를 통해 Dog 객체는 Animal 객체의 프로퍼티와 메서드를 상속받을 수 있습니다. max.speak() 메서드는 max 객체에서 직접 정의된 것이 아니지만, Animal.prototype으로부터 상속받아 사용할 수 있습니다.

프로토타입과 __proto__

JavaScript 객체는 모두 숨겨진 프로퍼티 __proto__를 가지고 있으며, 이는 객체의 프로토타입을 가리킵니다. __proto__는 ECMAScript 표준이 아니므로 최신 표준에서는 Object.getPrototypeOf()Object.setPrototypeOf() 메서드를 사용하는 것을 권장합니다. 예제를 통해 확인해 보겠습니다:

javascript
const myObj = {};
console.log(myObj.__proto__ === Object.prototype); // true

const arr = [];
console.log(arr.__proto__ === Array.prototype); // true

const func = function() {};
console.log(func.__proto__ === Function.prototype); // true

위 예제에서 myObj, arr, func 각각의 객체는 각각 자신의 생성자 함수(Object, Array, Function)의 프로토타입을 참조합니다. 이는 객체들이 공통된 프로퍼티와 메서드를 상속받을 수 있는 기반이 됩니다.

프로토타입의 활용

JavaScript의 프로토타입을 제대로 이해하고 활용하면 코드 재사용성과 성능을 크게 향상시킬 수 있습니다. 프로토타입을 사용하면 필요한 경우에만 메서드를 객체에 추가하여 메모리를 절약하고, 상속을 통해 코드를 더 모듈화할 수 있습니다.

특히, 프로토타입 체인을 통해 객체의 기능을 확장하고 재사용할 수 있습니다. 예를 들어, 다양한 타입의 객체에 공통된 기능을 프로토타입에 정의해 놓으면, 모든 객체가 이를 공유할 수 있어 효율적입니다:

javascript
Array.prototype.sum = function() {
  return this.reduce((acc, item) => acc + item, 0);
};

const numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // 15

위 예제에서, 배열(Array)에 sum 메서드를 추가함으로써 모든 배열 객체가 이 메서드를 사용할 수 있게 되었습니다. 이는 프로토타입을 통해 기능을 확장하는 매우 효율적인 방법입니다.

결론

JavaScript 프로토타입은 객체 지향 프로그래밍에서 중요한 개념입니다. 이를 이해하면 객체의 속성과 메서드를 더 효과적으로 관리할 수 있으며, 코드 재사용성과 효율성을 크게 높일 수 있습니다. 프로토타입 체인과 __proto__의 동작 방식을 이해하고, 이를 통해 객체 간의 상속 관계를 명확히 하면, JavaScript 코드를 작성할 때 큰 도움이 될 것입니다.