후기/코어 자바스크립트

코어 자바스크립트 - 클래스

태나미 2021. 10. 11. 13:06
이 글은 코어 자바스크립트 책에서 클래스를 공부하고 정리하는 목적으로 남깁니다.

목표

  • 클래스와 인스턴스의 개념을 이해할 수 있습니다.
  • 자바스크립트는 어떻게 클래스 상속을 구현한 것처럼 보이는지 알 수 있습니다.

목차

  1. 클래스와 인스턴스의 개념 이해
  2. 자바스크립트의 클래스
  3. 클래스 상속
  4. ES6의 클래스 및 클래스 상속
  5. 정리

클래스와 인스턴스의 개념 이해

자바스크립트는 프로토 타입 기반 언어라서 '상속'개념이 존재하지 않지만, ES6 이후 클래스 문법이 추가되고, 클래스 문법에서도 일정 부분은 프로토타입을 활용하고 있습니다.

class라는 의미는 '계급, 집단, 집합'등의 의미로 번역됩니다. 프로그래밍 언어적으로도 동일한 개념으로 접근하면 됩니다.

클래스 간의 상하관계

클래스(class)는 어떤 사물의 공통 특성을 모아 정의한 추상적인 개념입니다. 상위 클래스(SuperClass )와 하위 클래스(SubClass)로 나뉠 수 있습니다

인스턴스(instance)는 특정 클래스의 속성을 지니는 실존하는 사례입니다.

 

클래스는 하위로 갈수록 상위 클래스의 속성을 상속하면서 구체적인 요건이 추가되거나 변경됩니다.

하나의 인스턴스는 하나의 클래스만을 바탕으로 만들어집니다.

자바스크립트의 클래스

예시와 같이 알아보겠습니다.

 

  • 생성자 함수 Array를 new 연산자와 함께 호출하면 인스턴스가 생성됩니다.
  • Array를 클래스라고 보면,  Array의 prototype 객체 내부 요소들이 인스턴스에 '상속' 된다고 볼 수 있습니다. (정확히는 프로토타입 체이닝에 의한 참조)
  • 인스턴스에 상속되는지(인스턴스가 참조되는지) 여부에 따라 스태틱 멤버(static methods와 static properties가 있는)와 프로토타입 메서드로 구분됩니다.

프로토타입 클래스 개념 적용

// 생성자
var Rectangle = function (width, height) {
  this.width = width;
  this.height = height; 
};

// (프로토타입) 메서드
Rectangle.prototype.getArea = function() {
  return this.width * this.height;
};

// 스태틱 메서드
Rectangle.isRectangle = function(instance) {
  return instance instanceof Rectangle &&
  	instance.width > 0 && instance.height > 0;
};

var rect1 = new Rectangle(3,4);

console.log(rect1.getArea()); // 12
console.log(rect1.isRectangle()); // Error: rect1.isRectangle is not a function
console.log(Rectangle.isRectangle(rect1)); // true
  • getArea는 rect1.__proto__.getArea에 접근하는데, __proto__가 생략했으므로, this가 rect1채로 실행되어 해당 메서드의 값이 반환됩니다. 이처럼 인스턴스에 직접 호출할 수 있는 메서드프로토타입 메서드라고 합니다. 
  • rect1에 isRectangle메서드가 있는지 검색했는데 없고, rect1.__proto__에도 없으며, Object.prototype에도 없는 걸 알고, 함수가 아니어서 실행할 수 없다는 에러가 발생합니다. 이렇게 인스턴스에서 직접 접근할 수 없는 메서드스태틱 메서드라고 합니다. 스태틱 메서드는 생성자 함수를 this로 해야 호출할 수 있습니다.

클래스 상속

클래스 상속을 흉내 내기 위한 세 가지 방법이 있습니다.

 

  1. SubClass.prototype에 SuperClass의 인스턴스를 할당한 다음 프로퍼티를 모두 삭제하는 방법
  2. 빈 함수(Bridge)를 활용하는 방법
  3. Object.create를 이용하는 방법

ES6의 클래스 및 클래스 상속

var ES5 = function (name) {
  this.name = name;
};

ES5.staticMethod = function() {
  return this.name + ' staticMethod';
};

ES5.prototype.method = function() {
  return this.name + ' method';
};

var es5Instance = new ES5('es5');
console.log(ES5.staticMethod); // ES5 staticMethod 
console.log(es5Instance.method); // es5 method

var ES6 = class {
  constructor (name) {
    this.name = name;
  }
  
  static staticMethod () {
    return this.name + ' staticMethod';
  }
  
  method () {
    return this.name + ' method';
  }
}

var es6Instance = new ES6('es6');
console.log(ES6.staticMethod()); // ES6 staticMethod 
console.log(es6Instance.method()); // es6 method

ES5와 ES6의 클래스 문법을 비교

 

  • 클래스 문법에서 constructor는 ES5의 생성자 함수와 동일한 역할을 수행합니다.
  • static 키워드는 해당 메서드가 static 메서드임을 알리는 내용으로 생성자 함수(클래스) 자신만 호출할 수 있습니다.
  • method()는  prototype 객체 내부에 할당되는 메서드로, 인스턴스가 프로토타입 체이닝을 통해 자신의 것처럼 호출할 수 있는 메서드입니다.
var Rectangle = class {
  constructor (width, height) {
    this.width = width;
    this.height = height;
  }
  
  getArea() {
    return this.width * this.height;
  }
};

var Square = class extends Rectangle {
  constructor (width) {
    super(width, width);
  }
  
   getArea() {
    console.log('size: ', super.getArea());
  }
}

ES6의 클래스 상속

 

  • ES6의 클래스 문법에서의 상속받는 SubClass를 만들기 위해 class 명령 뒤 extends 키워드와 상속받고 싶은 SuperClass를 적으면 상속 관계 설정이 끝납니다.
  • constructor 내부에는 super라는 키워드를 함수처럼 사용할 수 있는데, 이는 SuperClass의 constructor를 실행합니다.

정리

  • 자바스크립트는 프로토타입 기반 언어
  • 프로토타입을 기반으로 클래스와 비슷하게 동작하게끔 하는 기법들이 도입돼 왔음

클래스와 인스턴스

  • 어떤 사물의 공통 특성을 모아 정의한 추상적인 개념
  • 인스턴스는 클래스의 속성을 지니는 구체적인 사례
  • 상위 클래스(superclass)의 조건을 충족하면서 더욱 구체적인 조건이 추가된 것을 하위 클래스(subclass)라고 함

메서드

  • 클래스의 prototype 내부에 정의된 메서드는 프로토타입 메서드라고 함
  • 프로토타입 메서드는 인스턴스가 마치 자신의 것처럼 호출할 수 있음
  • 클래스(생성자 함수)에 직접 정의한 메서드는 스태틱 메서드라고 함
  • 스태틱 메서드는 인스턴스가 직접 호출할 수없고 클래스(생성자 함수)에 의해서만 호출할 수 있음

클래스 상속을 흉내 내기 위한 세가지 방법

  • SubClass.prototype에 SuperClass의 인스턴스를 할당한 다음 프로퍼티를 모두 삭제하는 방법
  • 빈 함수(Bridge)를 활용하는 방법
  • Object.create를 이용하는 방법

ES6

  • 클래스 문법이 도입됨
  • 이전까지는 상속 및 추상화를 구현하기 위해 상당히 복잡한 방법을 사용했는데 ES6에서는 상당히 간단하게 처리됨

 

 

이미지 출처: https://juicyjerry.tistory.com/161