JS에서는 모든 객체는 프로토타입(prototype)이라는 내부 링크를 가집니다.
프로토타입은 해당 객체의 원형으로서, 다른 객체의 기반으로 사용될 수 있습니다.
객체를 생성할 때, 그 객체는 자신의 프로토타입을 상속받습니다.
이 상속은 프로토타입 체인(prototype chain)을 통해 이루어집니다.
예를 들어, 객체A의 프로토타입이 객체 B이고, 객체 B의 프로토타입이 객체 C라면, 객체A는 객체B를 상속하고, 객체 B는 객체 C를 상속하게 됩니다.
이런식으로 프로토 타입 체인을 따라 올라가면, Object.prototype에 도달하게 됩니다. Object.prototype은 모든 객체의 최상위 프로토 타입입니다.
프로토타입을 이용하면 객체들 간에 메서드와 속성을 공유할 수 있습니다.
예를 들어, 객체 A와 B와 모두 같은 메서드를 가지고 있을 때, 이 메서드를 A와 B 모두 사용하기 위해, A와 B의 프로토타입에 해당 메서드를 추가 할 수 있습니다.
프로토타입은 객체 리터럴을 통해 직접 생성할 수 있습니다. 예를 들어 이런식으로 프로토타입을 생성할 수 있습니다.
let myPrototype = {
method1: function(){....}
method2: function(){....}
};
이제 다른 객체에서 이 프로토 타입을 상속받을 수 있게 됩니다.
let myObject = Object.create(myPrototype);
또한 객체의 프로토타입은 Object.getPrototypeOf 메서드를 통해 접근할 수 있습니다
let myPrototype = {
method1: function(){....}
method2: function(){....}
};
let myObject = Object.create(myPrototype);
let myPrototype2 = Object.getPrototypeOf(myObject);
★예제
function Person(name) { //person이라는 생성자함수를 만들었다
this.name = name; //name이라는 인자를 받아 인스턴스에 name 속성에 할당한다
}
Person.prototype.greet = function() { //greet메소드를 프로토타입으로 추가하고 있다
console.log(`Hello, my name is ${this.name}`);
}
function Student(name, grade) { //Student 생성자함수는 person과 비슷하지만 grade라는 인자를 추가로 받고, 생성자 함수내에서 인스턴스의 name과 grade속성을 할당하고 있습니다
this.name = name;
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype); // student의 프로토타입을 object.create를 통해 person의 프로토타입을 상속 받도록 설정합니다
Student.prototype.constructor = Student; //constructor 프로퍼티를 student로 다시 지정해줍니다.
Student.prototype.greet = function() {//그리고 greet 메소드를 오버라이드하여 'student'에 맞게 수정합니다
console.log(`Hello, my name is ${this.name} and I'm in grade ${this.grade}`);
}
const john = new Person('John');
const jane = new Student('Jane', 9);
//마지막으로 'person'과 'Student'인스턴스를 생성하고,'greet'메소드를 호출하고 있습니다.
john.greet();
jane.greet();
이렇게 되면
Person의 greet 메소드가 호출되어
"Hello, my name is John"이 출력됩니다.
jane은 Student 인스턴스이므로 Student의 greet 메소드가 호출되어 "Hello, my name is Jane and I'm in grade 9"가 출력됩니다.