[TIL] 프로토타입

ㅜㅜ·2022년 9월 21일
1

Today I learn

목록 보기
21/77
post-thumbnail

프로토타입

자바스크립트는 프로토타입 기반 언어라고 불린다.
프로토타입은 원형 객체를 말한다.

앞서 객체 지향 프로그래밍에 대해서 배우면서 클래스 등을 배웠지만,
프로토타입에 대해 검색하면서 자바스크립트에는 클래스라는 개념이 없었고 대신 프로토타입이 존재했다는 걸 알게 되었다. (ES6에서 class 문법이 추가되었으나 자바스크립트가 클래스 기반으로 바뀐 것은 아님)

참고

class Human {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sleep() {
    console.log(`${this.name}은 잠에 들었습니다`);
  }
}

let kimcoding = new Human('김코딩', 30);


Human.prototype.constructor === Human; //true: Human 클래스의 프로토타입 객체의 생성자는 Human 함수
Human.prototype === kimcoding.__proto__; //true: Human의 프로토타입 객체는 Human 클래스의 인스턴스 kimcoding의 __proto__과 같다.
Human.prototype.sleep === kimcoding.sleep; //true: Humam클래스의 sleep 매서드는 프로토타입 객체에 있으며, Human 클래스의 인스턴스 kimcoding에서 sleep 매서드를 실행할 수 있다.


*우리가 흔히 쓰는 배열 역시 Array 클래스의 인스턴스이며, 프로토타입에 다양한 매서드(ex:.push,.slich,.map,.each)가 존재한다.




프로토타입 체인

자바스크립트에서 상속을 구현할 때 프로토타입 체인을 이용한다.
부모 클래스의 프로토타입, 부모의 부모 클래스 프로토타입을 탐색할 수 있는 proto가 부모 객체의 프로퍼티나 메소드를 검색하는 것을 프로토타입 체인이라고 한다.

자바스크립트 객체는 속성을 저장하는 동적인 "가방"과 (자기만의 속성이라고 부른다) 프로토타입 객체에 대한 링크를 가진다. 객체의 어떤 속성에 접근하려할 때 그 객체 자체 속성 뿐만 아니라 객체의 프로토타입, 그 프로토타입의 프로토타입 등 프로토타입 체인의 종단에 이를 때까지 그 속성을 탐색한다. (출처 : MDN)

  • extends 키워드
    : 상속 받을 클래스를 명시한다.
//부모 클래스
class Person {
  constructor(first, last, age, gender, interests) {
    this.name = {
      first,
      last
    };
    this.age = age;
    this.gender = gender;
    this.interests = interests;
  }

  greeting() {
    console.log(`Hi! I'm ${this.name.first}`);
  };

  farewell() {
    console.log(`${this.name.first} has left the building. Bye for now!`);
  };
}

//자식 클래스
class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    this.name = {
      first,
      last
    };

  this.age = age;
  this.gender = gender;
  this.interests = interests;
  //과목과 성적 속성은 Teacher만의 특징임
  this.subject = subject;
  this.grade = grade;
  }
}

  • super 키워드
    : 자식 클래스 내에서 부모 클래스의 생성자 함수를 호출하거나 자식 클래스에서 부모 클래스의 매소드 접근 역할을 한다. (부모 클래스의 함수를 호출할 때 사용된다.)
    생성자 함수 내에서 쓰일 때 super 키워드는 한 번만 사용될 수 있으며 this 키워드 사용 전에 사용되어야 함. 그렇지 않으면 reference 에러 발생.
class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);
		//부모 클래스의 생성자 호출 
		//이 아래는 Teacher만의 속성들
    this.subject = subject;
    this.grade = grade;
  }
}

//자식 클래스에서 인스턴스를 생성하면 부모 클래스 매소드 접근이 가능해진다.
let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
snape.greeting(); // Hi! I'm Severus.
snape.farewell(); // Severus has left the building. Bye for now.
snape.age // 58
snape.subject; // Dark arts

자식 클래스에서는 따로 부모 클래스 매서드를 입력하지 않아도 인스턴스 객체를 만들었을 때 사용 가능하다.
위의 예에서 snape 인스턴스에서 greeting()이라는 매서드를 사용가능한 이유는 Teacher 클래스가 Person 클래스의 자식 클래스이기 때문이다. 그러므로 부모 클래스의 매서드인 greeting()을 자식 클래스에서 사용 가능하다.





DOM과 프로토타입

  • DOM도 프로토타입으로 상속을 구현했다.
  • proto를 이용하면 부모 클래스의 프로토타입 or 부모의 부모 클래스의 프로토타입을 탐색할 수 있다.

let div = document.createElement('div');

div.__proto__ //HTMLDivElement
div.__proto__.__proto__ // HTMlElement
div.__proto__.__proto__.__proto__ // Element
div.__proto__.__proto__.__proto__.__proto__ // Node
div.__proto__.__proto__.__proto__.__proto__.__proto__ // EventTarget
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__ //Object
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__ //null 
let div = document.createElement('div')
document.body.append(div);
div.textContent = "데마시아!!!!"
div.addEventListener("click",() => console.log("럭스 짱"));

위의 예시에서 div가 addEventListener 매서드를 사용할 수 있는 이유는 EventTarget을 상속하고 있기 때문이다.

최상위 클래스 Object => EventTarget => Node => Element => HTMLElement => HTMLDivElement 순으로 상속한다.





오답노트

  • default parameter 를 이용하면 오늘 풀었던 beesbeesbees 문제를 풀 때 테스트도 통과시킬 수 있고, 원래 클래스(템플릿의 용도)처럼 사용할 수도 있었다.
    디폴트 파라미터는 매개변수에 값이 없거나, undefined가 전달인자로 전달 되었을 때, 대신 전달될 값을 말한다.
function multiply (a, b=1){
  return a * b
} // b에 할당된 1가 디폴트 파라미터

console.log(multiply(5, 2));//10
console.log(multiply(5));//5
profile
다시 일어나는 중

0개의 댓글