Prototype(프로토타입)
JavaScript에서 프로토타입은 다른 객체를 만들기 위한 청사진 역할을 하는 객체다. 이는 JavaScript 객체 지향 프로그래밍의 필수 부분으로, 프로토타입에서 속성과 메소드를 상속하는 객체를 생성할 수 있다. 이 상속 메커니즘을 프로토타입 상속이라고 한다.
프로토타입 객체는 두 가지 기본 용도로 사용된다.
- 상속: 객체는 프로토타입에서 속성과 메소드를 상속할 수 있다.
- 코드 재사용성: 프로토타입을 사용하여 공유 속성 및 메소드를 정의하여 코드 중복을 줄일 수 있다.
이 개념을 이해하기 위해 생성자 함수와 프로토타입을 사용하여 간단한 예제를 만들어보자.
// Car 객체를 생성하기 위한 생성자 함수
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
// Car 프로토타입에 메소드 추가
Car.prototype.getDetails = function() {
return this.make + ' ' + this.model + ' (' + this.year + ')';
};
// 새로운 Car 객체 만들기
var car1 = new Car('Toyota', 'Corolla', 2019);
var car2 = new Car('Honda', 'Civic', 2020);
// Car 프로토타입의 getDetails 메소드 사용
console.log(car1.getDetails()); // "Toyota Corolla (2019)"
console.log(car2.getDetails()); // "Honda Civic (2020)"
1. Car라는 생성자 함수를 만든다. new 키워드로 호출하면 make, model 및 year 속성이 있는 새 객체를 만든다.
2. 그런 다음 Car 프로토타입에 getDetails라는 메소드를 추가한다. 프로토타입에 이 메소드를 추가하면 모든 Car 인스턴스가 이 메소드를 상속한다. 이렇게 하면 각 인스턴스가 고유한 메소드 복사본을 만들 필요가 없으므로 메소드를 한 번만 정의하고 메모리를 절약할 수 있다.
3. 다음으로 new 키워드로 Car 생성자 함수를 호출하여 car1 및 car2라는 두 개의 새로운 Car 객체를 만든다. 이러한 각 객체는 getDetails 메소드를 포함하여 Car 프로토타입에 정의된 속성과 메소드를 상속한다.
4. 마지막으로 car1과 car2 모두에서 getDetails 메소드를 호출한다. 이러한 객체는 Car 프로토타입에서 상속되므로 getDetails 메소드에 액세스하고 사용할 수 있다. 출력에는 각 자동차의 제조업체, 모델 및 연도가 표시되어 메소드가 예상대로 작동하고 있음을 보여준다.
이를 통해 생성자 함수의 인스턴스에서 상속할 수 있는 공유 속성 및 메소드를 정의할 수 있다. 이는 코드 재사용성과 효율적인 메모리 사용을 촉진한다.
Prototype Chain
프로토타입 체인은 일련의 연결된 프로토타입을 통해 객체 상속을 가능하게 하는 JavaScript의 기본 개념이다. 객체가 생성되면 프로토타입에서 속성과 메소드를 상속한다. 프로토타입 자체는 고유한 프로토타입을 가질 수 있고 또 다른 프로토타입을 가질 수 있다.
이 연결된 프로토타입 체인을 프로토타입 체인이라고 한다.
프로토타입 체인의 작동 원리를 살펴보자.
1. 객체의 속성이나 메소드에 접근하려고 할 때, 자바스크립트는 먼저 해당 객체 자체에서 속성이나 메소드를 찾는다.
2. 객체 자체에 속성이나 메소드가 없으면, 자바스크립트는 객체의 프로토타입에서 찾는다.
3. 해당 프로토타입에도 속성이나 메소드가 없으면, 자바스크립트는 그 프로토타입의 프로토타입을 찾아 계속해서 프로토타입 체인을 따라 상위 프로토타입을 검색한다. 이러한 과정은 속성이나 메소드를 찾거나 프로토타입 체인의 끝에 도달할 때까지 반복된다. 프로토타입 체인의 끝은 대개 내장된 Object.prototype이다.
4. 만약 속성이나 메소드가 프로토타입 체인 전체에서 찾아지지 않으면, 자바스크립트는 undefined를 반환한다.
프로토타입 체인의 예제를 통해 개념을 더 확실히 이해해보자.
// Person 생성자 함수
function Person(name) {
this.name = name;
}
// Person 프로토타입에 메소드 추가
Person.prototype.sayName = function () {
return '내 이름은 ' + this.name;
};
// Employee 생성자 함수
function Employee(name, jobTitle) {
Person.call(this, name); // Person에서 속성 상속
this.jobTitle = jobTitle;
}
// Person 프로토타입을 상속받는 새 객체 생성
Employee.prototype = Object.create(Person.prototype);
// 생성자를 다시 Employee로 설정
Employee.prototype.constructor = Employee;
// Employee 프로토타입에메소드 추가
Employee.prototype.getJobTitle = function () {
return this.jobTitle;
};
// 새로운 Employee 인스턴스 생성
var employee1 = new Employee('홍길동', '소프트웨어 엔지니어');
// Person과 Employee 프로토타입 모두에서 메소드 사용
console.log(employee1.sayName()); // "내 이름은 홍길동"
console.log(employee1.getJobTitle()); // "소프트웨어 엔지니어"
1. 이 예제에서는 두 개의 생성자 함수인 Person과 Employee를 생성한다. Person 생성자 함수는 sayName 메소드를 프로토타입에 정의하고 있다. Employee 생성자 함수는 Person의 하위 클래스로서, Person의 속성과 메소드를 상속해야 한다.
2. 이를 위해 Employee 생성자 함수 내에서 Person.call(this, name)을 사용하여 Person의 속성을 상속한다.
3. 다음으로, Object.create(Person.prototype)을 사용하여 Person.prototype에서 프로토타입을 상속받는 새 객체를 생성한다. 이 새 객체를 Employee.prototype에 할당함으로써 Employee 프로토타입을 Person 프로토타입에 연결하고 프로토타입 체인을 만든다. 또한, 올바른 생성자 참조를 유지하기 위해 Employee.prototype.constructor를 Employee로 설정한다.
4. 이제 Employee 프로토타입에 getJobTitle 메소드를 추가한다. 이 메소드는 Employee 인스턴스에만 특화되어 있으며, Person 프로토타입에는 없다.
5. employee1이라는 새로운 Employee 인스턴스를 생성한다. Employee가 Person으로부터 상속되므로, employee1은 Person 프로토타입의 sayName 메소드와 Employee 프로토타입의 getJobTitle 메소드에 모두 접근할 수 있다.
6. employee1에서 sayName과 getJobTitle 메소드를 호출할 때, 자바스크립트는 프로토타입 체인을 따라 이러한 메소드를 찾는다.
7-1. sayName의 경우, 자바스크립트는 먼저 Employee 프로토타입을 확인한 후, 해당 메소드를 찾지 못하면 상위 프로토타입인 Person 프로토타입에서 찾게 된다. 여기에서 메소드를 찾아 호출하며, 출력 결과는 "내 이름은 홍길동"이 된다.
7-2. getJobTitle 메소드의 경우, 자바스크립트는 먼저 Employee 프로토타입에서 메소드를 찾는다. 해당 메소드가 존재하므로, 이를 호출하고 출력 결과는 "소프트웨어 엔지니어"가 된다.
결론적으로, 프로토타입 체인은 자바스크립트에서 객체 상속을 지원하는 중요한 개념이다. 프로토타입 체인은 연결된 프로토타입의 시리즈를 통해 객체들이 속성과 메소드를 상속할 수 있게 하며, 자바스크립트는 속성이나 메소드를 찾기 위해 이 체인을 따라 검색을 수행한다.
이러한 방식은 객체 지향 프로그래밍에서 코드 재사용성과 확장성을 향상시키는 데 도움이 된다. 서로 다른 생성자 함수와 프로토타입을 사용하여 다양한 객체 타입과 계층 구조를 정의할 수 있으며, 이를 통해 더 복잡한 어플리케이션을 구축할 수 있다.
프로토타입 체인의 이해는 자바스크립트 프로그래밍의 근간이므로, 이 개념을 활용하여 효율적이고 유지 관리가 쉬운 코드를 작성하는 것이 중요하다. 프로토타입 체인을 사용하여 객체 간의 관계를 구축하고, 상속을 통해 기존의 속성과 메소드를 확장하고 재사용함으로써, 자바스크립트에서 객체 지향 프로그래밍의 장점을 최대한 활용할 수 있다.