본문 바로가기

Javascript/Others

chatGPT와 JavaScript 공부:프로토타입(Prototype)

반응형

 

chatGPT와 JavaScript 공부:프로토타입(Prototype)

이번 포스트에서는 JavaScript의 프로토타입(Prototype)에 대해 공부해 보고자 한다.
JavaScript를 유튜브 강의나 다른 유료 강의를 통해 사용법에 대해서만 중점적으로 공부했었어서 사실 이번에 처음 알게 됐다.
프로토타입은 JavaScript의 객체 지향 프로그래밍 구조(OOP)를 구성하는 중요한 기능으로, 객체 간의 상속 및 메서드 공유를 가능하게 한다고 한다.
사실 이 정도 설명만 들었을 때는 Python에서의 class같은 거 아닌가? 하고 생각했었는데
알아보니 Python, JAVA는 class 언어이고 JavaScript는 prototype 언어라고 한다.
JavaScript에서도 class가 있지만 ES6부터 사용 가능했고, 그렇다고 해서 JavaScript가 Python이나 JAVA처럼 class 기반의 언어인 것은 아니다.
중요한 개념이라는데 사실 좀 어렵다.
도와줘요 GPT...!
Question
JavaScript의 Prototype에 대해서 설명해줘
Answer
자바스크립트의 프로토타입(Prototypes)은 어떤 객체가 다른 객체로부터 속성과 메서드를 상속받을 수 있게 해주는 특징을 말합니다. 자바스크립트는 전통적인 클래스 기반의 상속이 아닌, 프로토타입 기반의 상속을 사용하는 언어입니다.
객체는 __proto__라는 숨겨진 속성을 통해 자신의 프로토타입을 가리키며, 이 프로토타입 객체 역시 다른 프로토타입을 가리킬 수 있습니다. 이렇게 연결된 프로토타입들을 프로토타입 체인(Prototype Chain)이라고 합니다.

예시-1
let animal = {
  kind: "animal",

  shout: function () {
    console.log("I'm an animal!");
  },
};

let dog = Object.create(animal);
dog.kind = "dog";

console.log(dog.kind); // "dog"
dog.shout(); // "I'm an animal!"

위 코드에서 Object.create 메서드를 사용하여 animal 객체를 프로토타입으로 하는 dog 객체를 생성했습니다. 이렇게 하면 dog 객체는 animal 객체의 속성과 메서드를 상속받게 됩니다.

이제 dog 객체에는 kind 속성이 있지만, shout 메서드는 없습니다. 그럼에도 불구하고 dog.shout()를 호출하면 "I'm an animal!"이 출력됩니다. 이는 dog 객체의 프로토타입 체인을 통해 shout 메서드를 찾아 호출하기 때문입니다.

이처럼 프로토타입은 자바스크립트의 핵심 특징 중 하나로, 객체 지향 프로그래밍의 상속, 메서드 오버라이딩(Overriding), 다형성(Polymorphism) 등의 개념을 구현하는 데 사용됩니다.
저 예시에서 보면 dog 객체는 결국 animal 객체를 상속받아서 animal이 가진 속성, 메서드를 dog도 동일하게 가져간다는 것.
아래 사진을 참고하면 될 것 같다.



dog를 처음 선언했을 때는 빈 객체({})이다.
하지만 [[Prototype]]을 확인하면 kind와 shout을 확인할 수 있는데,
이렇게 상속을 시켜주고 dog.kind를 하면 현재 dog는 빈 객체이지만 Prototype으로 연결된 kind를 찾아낸다.
즉, dog.kind는 'animal'를 출력해 준다.
그리고 그 후에 dog.kind='dog'로 수정해 준 후 dog 객체를 다시 출력해 보면,
이번에는 비어있는 객체가 아닌 {kind: 'dog'}가 되는 것을 확인할 수 있다.
dog.kind를 했을 때 dog 객체에는 kind가 존재하므로 이번에는 'dog'를 출력한다.
하지만 여전히 dog에는 shout 메서드는 선언되어 있지 않지만, Prototype을 통해 연결된 shout 메서드를 사용할 수 있게 된다.

animal 객체의 shout 메서드를 아래 처럼 수정하게 된다면,
dog.shout(); // I'm an animal!
animal.shout = function (){console.log("It's changed!")}; // animal의 shout 메서드를 수정
dog.shout(); // It's changed!

이렇게 dog의 shout 메서드도 함께 변경된다.

chatGPT에게 또 다른 예시를 출력해달라고 해보았다.
예시-2
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

Car.prototype.startEngine = function () {
  console.log('Engine starting...');
};

const car1 = new Car('Toyota', 'Camry', 2005);
const car2 = new Car('Honda', 'Accord', 2008);

car1.startEngine(); // "Engine starting..."
car2.startEngine(); // "Engine starting..."


위의 예시에서는 Car라는 생성자 함수를 정의하였고, Car.prototypestartEngine이라는 메서드를 추가하였습니다. 이렇게 하면 new Car()를 통해 생성된 모든 인스턴스는 startEngine 메서드를 공유하게 됩니다.

그리고 new Car('Toyota', 'Camry', 2005)를 호출하여 car1 객체를 생성하고, new Car('Honda', 'Accord', 2008)를 호출하여 car2 객체를 생성했습니다. 이 두 객체는 각각 다른 속성값(make, model, year)을 가지고 있지만, 동일한 startEngine 메서드를 공유하고 있습니다. 이는 startEngine 메서드가 Car의 프로토타입에 정의되어 있기 때문입니다.

이렇게 프로토타입을 사용하면 메서드를 모든 인스턴스에 복사하지 않고, 한 곳에 정의하여 모든 인스턴스가 공유하도록 할 수 있습니다. 이는 메모리를 효율적으로 사용할 수 있게 하며, 모든 인스턴스가 동일한 동작을 보장할 수 있습니다.
Python의 class와 비슷한 개념으로 느껴진다.
Python의 class는 '틀'이나 '청사진'과 같은 역할을 한다.
이를 통해 객체(인스턴스)를 생성하고, 이때 생성된 객체는 해당 class에서 정의된 모든 속성과 메서드를 가지게 된다.
또한 class는 다른 class로부터 상속을 받아 속성과 메서드를 확장할 수 있다.

JavaScript는 프로토타입 객체로부터 속성과 메서드를 상속받을 수 있다.
이때 프로토타입 체인을 통해 상속을 받을 수 있으며, 이는 모든 객체가 공통적으로 가지는 메서드와 속성을 공유할 수 있게 한다.

이번 것도 쉽진 않았지만 얼추 이해되는 것 같다.
예시-2에서 new Car를 보고 생각이 났는데, 추가로 알아보니 new Array도 마찬가지로 Array.prototype.METHOD = function(){...} 형식으로 작성하게 된다면 모든 Array에서 METHOD라는 별도로 생성한 함수를 사용할 수 있게 된다!
이 부분은 나중에 업무에 한번 활용해 봐야겠다!
반응형

loading