function Person(name, firstScore, secondScore) {
this.name = name;
this.firstScore = firstScore;
this.secondScore = secondScore;
this.sum = function() {
return this.firstScore + this.secondScore;
}
}
const kim = new Person('kim', 10, 20); // 새 객체 생성
console.log(kim);
// Person {
name: 'kim',
firstScore: 10,
secondScore: 20,
sum: [Function (anonymous)]
}
console.log(kim.name); // kim
console.log(kim.sum()); // 30
그러나 Person 생성자 함수 안에서 sum 메소드를 정의하는 것은 좋은 방법이 아니다. 왜냐하면 새 객체를 생성할 때마다 sum 메소드가 계속해서 새로 정의되기 때문에 메모리가 낭비된다. 따라서 객체 메소드를 정의할 때는 prototype을 이용해 생성자 함수 밖에서 정의하는 것이 좋다.
객체.prototype.함수명 = function(){}
생성자 함수 밖에서 prototype으로 메소드를 정의할 수 있다.
이때도 마찬가지로 객체 자신을 가리킬 때 this를 쓴다.
function Person(name, firstScore, secondScore) {
this.name = name;
this.firstScore = firstScore;
this.secondScore = secondScore;
}
// 프로토타입으로 메소드 정의
Person.prototype.sum = function () {
return this.firstScore + this.secondScore;
}
const kim = new Person('kim', 10, 20);
console.log(kim.sum()); // 30 (프로토타입 메소드 호출)
const lee = new Person('lee', 10, 30);
// lee라는 객체에서 프로토타입 메소드를 해당 객체 내 메소드로 변경
lee.sum = function () {
return 'lee: ' + (this.firstScore + this.secondScore);
}
console.log(lee.sum()); // lee: 40 (lee 객체 내 메소드 호출)
prototype으로 정의한 메소드를 특정 객체에서 변경하려면
객체.함수명 = function(){수정된 함수}
이렇게 해당 객체에만 속하는 메소드로 만들 수 있다.
객체의 메소드가 호출될 때,
1) 해당 객체에서 정의된 메소드객체.함수명 = function(){}
2) prototype으로 정의된 메소드객체.prototype.함수명 = function(){}
순서로 호출된다. 특수 케이스가 일반 케이스보다 먼저 적용되는 것.
위 예시에서 lee객체는 lee객체에서 정의한 메소드가 호출되고, kim객체는 kim객체에서 정의한 메소드가 없으므로 prototype에서 정의한 메소드가 호출된다.