const Food = function (name) {
this._name = name;
};

Food.prototype.getName = function () {
console.log(this);

return this._name;
};

var zzam = new Food("zzampong");
zzam.**proto**.getName();          // (1)
console.log(zzam.getName());       // (2)

(1)과 (2)에서 this가 가리키는 것은 무엇이고, 왜 다른가요?

(1)과 (2)에서 **this**가 가리키는 것이 다른 이유는 JavaScript에서 메서드 호출 방법에 의해 결정됩니다.

  1. **(1)**에서 **zzam.__proto__.getName();**을 호출할 때, 직접 zzam 객체의 __proto__ 프로퍼티를 통해 getName 메서드를 호출하고 있습니다. 이 경우 **this**는 zzam.__proto__ 객체를 가리킵니다.
  2. **(2)**에서 **zzam.getName();**을 호출할 때, zzam 객체의 getName 메서드를 호출하고 있습니다. 이 경우 **this**는 zzam 객체를 가리킵니다.

따라서 **(1)**과 **(2)**에서 **this**가 가리키는 것이 다른 이유는 메서드 호출의 방식에 따라 달라지며, 첫 번째 경우에는 프로토타입 객체를, 두 번째 경우에는 실제 객체를 가리키기 때문입니다.

실제로 **(1)**에서 **zzam.__proto__.getName();**를 호출할 때, **__proto__**를 통해 프로토타입 체인을 따라 getName 메서드를 호출하는 것은 권장되지 않습니다. 대신 **(2)**와 같이 객체 인스턴스의 메서드를 직접 호출하는 것이 더 바람직합니다. 이것은 코드의 가독성을 향상시키고 예기치 않은 동작을 방지할 수 있습니다.

부모 객체에서 상속된 메서드를 자식 객체에서 다시 정의하거나 수정하는 것을 의미

상속된 메서드를 자신의 필요에 맞게 재정의하거나 확장

다형성은 동일한 메서드 이름을 가진 여러 객체가 서로 다른 동작을 수행할 수 있음을 의미