S2_U2_CH2. 프로토타입

Judevv·2023년 5월 12일
0

Chapter 2. 프로토타입

학습 목표

  • 프로토타입이 무엇인지 설명할 수 있다.
  • 프로토타입과 클래스의 관계에 대해 설명할 수 있다.
  • 프로토타입 체인에 대해 설명할 수 있다.

2-1. 프로토타입과 클래스

  • JavaScript는 프로토타입(Prototype) 기반 언어

    • 모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 의미
    • 프로토타입 객체도 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수 있고, 그 상위 프로토타입 객체도 마찬가지(프로토타입 체인)
  • 프로토타입(Prototype)

    • 상속을 구현하는 방식 중 하나
    • 객체가 생성될 때 자동으로 생성되고, 해당 객체의 원형 역할
    • 객체가 가지고 있는 속성과 메서드를 정의하는 객체
    • ex) 어떤 객체의 프로토타입이 다른 객체인 경우, 전자는 후자의 속성과 메서드를 상속 받게 됨
// person 객체를 정의하고, 이 객체의 프로토타입으로부터 상속받은 sayHello 메서드를 호출하는 예제

// Person 객체 정의 - 자동으로 프로토타입 생성
function person(name) {
  this.name = name;
} 

// person.prototype 속성에 저장
// 이 객체에 메서드를 추가하면 person 객체를 생성할 때 만들어지는 모든 객체가 상속 받음	

// person 객체의 프로토타입에 sayHello 메서드 정의
person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

// person 객체 생성
var person1 = new person("Alice");

// person 객체의 프로토타입으로부터 상속받은 sayHello 메서드 호출
person1.sayHello(); // 출력: "Hello, my name is Alice"

🤔) 내가 프로토타입을 이해하는 방법
보통 프로그래밍이 아닌 산업에서의 프로토타입은 제품이 나오기 전에 시험용으로 먼저 만들어보는 시제품을 프로토타입이라고 말하는데, JavaScript의 프로토타입도 비슷하게, 어떤 객체가 생성되기 전에 시객체(?)로 본래의 기능과 컨셉이 있었던 것이다... 라고 이해해도 될지?

객체가 생성될 때 자동으로 생성되는 원형 객체니까, 이 원형 객체는 생성된 객체의 원래 기능과 컨셉을 가지고 있고, 상속받는 객체는 원형 객체의 기능과 컨셉을 계승하게 되는 것. 프로토타입은 객체가 나오기 전에 먼저 만들어져 있어야 하는 것?

예를 들면, a객체가 부모 객체인 프로토타입을 가지고 있고, b객체는 a객체에서 상속받은 기능과 속성을 가진 자식 객체일 때,

a 객체는 b 객체의 프로토타입이 되고, b 객체는 a 객체에서 상속받은 기능과 속성을 계승하게 됨

b 객체는 a 객체의 원래 기능과 컨셉을 가지고 있으며, 이를 상속받아서 자신만의 기능과 속성을 추가할 수 있음!

혹시 이걸 보는 누군가가 있다면 틀렸으면 댓글로 알려주십쇼(ㅜㅜ)

  • .prototype.__prototype__
    • .prototype
      • 생성자 함수가 생성할 인스턴스 객체의 프로토타입을 설정하는 속성
      • 생성자 함수가 인스턴스 객체를 만들 때마다 .prototype 속성에 정의된 속성과 메서드를 인스턴스 객체가 상속받게 됨!!!!
      • 생성자 함수가 만든 객체가 공유할 메서드나 속성을 정의함!!!!
    • .__prototype__
      • 객체의 프로토타입에 접근할 수 있는 속성
      • 모든 객체는 .__proto__ 속성을 가지는데, 이 속성은 해당 객체가 상속받은 부모 객체를 가리킴

  • 클래스와 인스턴스, 그리고 프로토타입의 관계
    • 클래스는 객체를 만들기 위한 일종의 템플릿이라고 생각하면 됨
    • 인스턴스는 클래스를 통해 생성된 어떤 객체를 말함
    • 클래스는 ES6에서 도입된 문법적 요소이고, 기존의 프로토타입 기반 상속 패턴을 간단하게 구현하기 위한 구문이라고 생각하면 됨
    • 클래스는 프로토타입을 기반으로 구현되어 있는데, 클래스로부터 생성된 인스턴스는 클래스의 프로토타입을 상속받아 자신의 프로토타입 체인을 구성함
    • 이를 통해 인스턴스는 클래스의 속성과 메서드를 상속받아 사용할 수 있게 됨
    • 결국 클래스와 인스턴스는 프로토타입과 밀접한 관계를 가지고 있다는 의미!!!
    • 클래스는 인스턴스를 생성하기 위한 청사진(blueprint)으로서 프로토타입의 개념을 가지고 있고, 인스턴스는 클래스의 프로토타입을 상속받아 자신의 프로토타입 체인을 구성할 수 있음

🤔) 프로토타입을 왜 참조한다고 표현하는가?
동기분의 질문에서 시작된 서치? 조사? 아무튼 이해한 방식?

프로토타입에서의 "참조"라는 말은 상속과 유사한 개념이라고 볼 수 있음
그러니까 프로토타입은 상속과 참조 두 가지의 개념을 모두 가지고 있다고 생각하면 됨

JavaScript에서 객체가 생성이 될 때, 자신의 프로토타입을 가리키는 어떤 링크인 '[[Prototype]]'을 가지고 있다고 함
이 링크는 부모 객체를 참조하게 되고, 자식 객체는 부모 객체의 속성과 메서드를 상속 받게 됨
서로 참조를 통해 연결되어 있다고 생각할 수 있음
프로토타입은 객체를 상속받는 데에 있어서 상속의 기본 개념인 '복제'보다 '참조'에 더 가까운 개념이라고 할 수 있음

그러니까 자식 객체의 속성을 변경할 때, 부모 객체의 속성도 함께 바뀌는 것이 아니라서 참조한다고 표현하는 것...

스터디원분께서 부모의 값이 바뀌면 자식의 값이 같이 바뀔 수 있기 때문에 참조한다고 표현하는 것 같다고 말씀해주셔서 이해가 뽝! 됐음
자식에서는 값을 변경할 수는 없지만, 부모에서 변경되면 그대로 상속되듯이 변경 되어서 내려오기 때문에... WOW


2-2. 프로토타입 체인

  • 객체의 상속 구조를 구현하기 위한 어떤 메커니즘
  • JavaScript에서 모든 객체는 prototype이라는 어떤 내부의 기능을 가지고 있음
    • 객체를 생성할 때 자신의 부모 객체를 가리키는 기능
    • 그 부모 객체도 자신의 부모 객체를 가리키는 기능을 가지고 있음
    • 이것을 반복해서 부모 객체의 부모 객체를 찾아가면, 결국 모든 객체는 Object.prototype까지 가게 되는데, 이런 연결 과정을 프로토타입 체인이라고 함(약간 족보 찾기?)
  • 프로토타입 체인은 객체가 상속받은 메서드나 속성을 검색할 때 주로 사용함
    • 객체에서 메서드나 속성을 찾을 때, 해당 객체가 없으면, 부모 객체인 프로토타입 객체에서 찾는 것
    • 상속된 메서드나 프로퍼티를 자식 객체에서 마치 자신의 것처럼 사용할 수 있음
  • 상속을 구현하는 키워드
    • extends
      • 자식 클래스가 부모 클래스를 상속받을 때 사용
      • extends 키워드 다음에 상속받을 부모 클래스의 이름을 적어줌
    • super
      • 자식 클래스에서 부모 클래스의 메서드나 생성자를 호출할 때 사용
      • 부모 클래스의 메소드를 그대로 사용할 수 있음
// 예시 코드

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
} 

// Animal은 name 속성과 speak() 메서드를 가지고 있음

class Dog extends Animal {
  speak() {
    super.speak();
    console.log(`${this.name} barks.`);
  }
} 
// Dog는 Animal을 상속하면서 speak() 메소드를 가져옴
// 그리고 새로운 내용을 추가

let dog = new Dog('Rufus');
dog.speak();

//Rufus makes a noise.
//Rufus barks.

// super.speak()를 사용하여 Dog 클래스에서 부모 클래스인 Animal 클래스의 speak() 메소드를 호출
// Dog 클래스에서 추가한 "barks."를 출력 
  • DOM과 프로토타입

    • DOM은 웹페이지의 HTML요소들을 객체 형태로 나타내는 모델

    • DOM 요소들도 객체고, 프로토타입 기반 상속을 사용

    • ex) HTML의 모든 요소는 HTMLElement를 상속받는데,HTMLElement는 Element를 상속받고, Element는 Node를 상속받고, Node는 EventTarget을 상속받음

      • 상속 관계가 계속 이어지고, 최종적으로 Object.prototype을 상속받게 됨
      • DOM에서 각 요소들은 그들의 프로토타입 체인을 따라 상위 객체의 메서드와 속성을 상속받는 것
    • 브라우저에서 DOM을 이용하면, document.createElement('div')로 새로운 div 엘리먼트를 만들 수 있는데, 이렇게 생성된 div 엘리먼트는, HTMLDivElement라는 클래스의 인스턴스가 됨

    • DOM 엘리먼트는 예를 들어 innerHTML과 같은 속성, 또는 append()와 같은 메서드가 있고, 각각의 엘리먼트가 해당 메서드나 속성이 있다는 것을 통해, Element라는 공통의 부모가 있음을 알 수 있음

    • div 엘리먼트의 상속 관계

  • 화살표 방향은 부모를 가리키고

  • EventTarget의 부모로는, 모든 클래스의 조상인 Object가 존재

  • 인스턴스의 __proto__를 이용하면 이를 더 확실하게 확인 가능

  • __proto__를 이용하면 부모 클래스의 프로토타입, 혹은 '부모의 부모 클래스'의 프로토타입을 탐색가능

profile
감성있는 개발자를 꿈꿔요

0개의 댓글