[JS] 클래스: ES6 Class와 프로토타입

donguraemi·2023년 8월 14일
0
post-thumbnail

Class

클래스는 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메서드를 정의한 일종의 틀이다. 클래스는 객체를 정의하기 위한 상태(멤버 변수)와 메서드(함수)로 구성된다.


ES6 Class

ES6 클래스 문법은 객체 지향적으로 표현하기 위해 새롭게 추가된 문법이다. ES6가 등장하기 전까진 prototype을 통해 클래스를 비슷하게 구현했다. 하지만 ES6의 클래스도 생김새만 다를 뿐, 내부적으로 프로토타입 방식으로 동작한다.

class는 내부적으로 프로토타입으로 동작하기 때문에 typeof로 타입을 출력할 경우, function을 반환한다.

// prototype (ES5)
let Meal = function(food) { // 생성자 함수
  this.food = food;
}
Meal.prototype.eat = function() {}; // 메서드
// class (ES6)
class Meal{
  constructor(food) { // 생성자
  	this.food = food;
  }
  eat() {} // 메서드
}

console.log(typeof Meal); // function

Prototype

자바스크립트는 프로토타입 기반 언어다. 자바스크립트의 객체는 prototype이라는 은닉 속성을 가지는데, 이는 자신의 프로토타입이 되는 다른 객체를 가리킨다.

앞서 설명했듯이 기존 자바스크립트는 클래스가 없어 함수를 통해 클래스를 흉내냈다.

function Person() {
	this.eyes = 2;
  	this.nose = 1;
}

let kim = new Person();
let park = new Person();

kimpark은 함수와 new를 통해 생성된 Person 객체다. 하지만 눈이 2개, 코가 1개라는 공통적인 특징을 가지고 있음에도 불구하고 eyesnose가 2개씩, 총 4개가 할당된다. 이러한 문제는 prototype으로 해결할 수 있다.

function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;

Person.prototype이라는 객체가 어딘가에 존재하고, eyesnose를 해당 객체에 넣어 kimpark이 공유하여 사용한다.

💥 ES6 class의 내부 동작 방식

class Meal{
  constructor(food) { // 생성자
  	this.food = food;
  }
  eat() {} // 메서드
}
  1. Meal이라는 이름을 가진 함수를 생성한다. 함수 본문은 생성자 메서드인 constructor에서 가져오며, 생성자 메서드가 없는 경우, 본문이 없는 함수가 생성된다.
  2. 클래스 내부에서 정의된 eatMeal.prototype에 저장한다.

es6 to prototype


클래스 정의 방법

  1. Class Declaration
class myClass {
  constructor() {}
  method1() {}
  method2() {}
}
  1. Class Expression : class 표현식은 이름을 가질 수도 있고, 익명으로 사용될 수도 있다.
let c1 = class MyClass {
    constructor() {}
    method1() {}
    method2() {}
};

let c2 = class {
  constructor() {}
  method1() {}
  method2() {}
};

접근 제한자

접근 제한자는 말 그대로 접근을 제한하기 위해 사용된다. 필요에 따라 클래스와 인터페이스를 다른 패키지에서 사용하지 못하도록 막을 필요가 있기 때문이다. 접근 제한자의 종류는 다음과 같다.

publicprotecteddefaultprivate
모든 접근 허용같은 패키지(폴더)의 객체와 상속관계의 객체들만 허용같은 패키지(폴더)에 있는 객체만 허용현재 객체 내에서만 허용

Javascript Class

class Meal{
  static beverage = 'coke';
  publicField;
  #privateField;
  
  constructor(food) { // constructor
  	this.food = food;
  }

  eat() {} // method

  get food() { // getter
    return this._food;
  }

  set food(val) { // setter
    this._food = val;
  }

  static getBeverage() { // static method (Meal.getBeverage로 호출)
    return this.beverage;
  }
}
  • constructor : class로 생성된 객체를 생성하고 초기화하기 위한 특수한 메서드다. constructor는 클래스 안에 하나만 존재할 수 있다. 만약 클래스에 여러 개의 constructor가 존재하는 경우, 에러가 발생한다.
  • method : getter나 setter의 경우 get과 set을 붙인다.
  • property : 프로퍼티는 크게 public과 private으로 나뉜다. public은 <instance name>.<property name>으로 프로퍼티의 값을 설정하고 읽을 수 있다. 반면, private은 클래스의 바깥에서 접근할 수 없다. 프로퍼티의 값은 <property name> = <value>로 설정할 수 있다.
  • static : 정적 메서드는 클래스의 인스턴스가 아닌 클래스 이름으로 곧바로 호출되는 메서드를 의미한다. 메서드명 앞에 static 키워드를 붙이면 해당 메서드는 정적 메서드가 된다.

💥 prototype에 저장되는 것과 아닌 것

prototype에 저장개별 객체에 저장
constructor, methodproperty

참고자료
JS class
mdn web docs : inheritance and prototype chain
JAVASCRIPT.INFO : class

0개의 댓글