[javascript] 클래스(Class)의 이해

클래스(Class) 는 ES6부터 자바스크립트에 도입된 기능입니다.

클래스는 새로운 종류의 객체를 만드는 구조를 제공합니다.

배열 객체는 배열 데이터를 처리하기 위한 속성과 메서드를 제공하고, 배열 데이터를 내부에 가지고 있습니다.

쇼핑몰을 구현하는 경우라면 장바구니 객체를 이용해 장바구니의 상품 목록을 관리하고, 장바구니의 상품 갯수, 합계를 표시하는 기능을 생각할 수 있습니다.

갯수와 합계는 프로퍼티 형태로 제공하고, 장바구니의 상품 추가/삭제/수정 은 메서드로 제공할 수 있습니다.

클래스로 장바구니 객체는 new 키워드로 객체를 실행해 실제 동작하는 객체를 할당해야 합니다.

특별히 이렇게 실행되어 변수에 할당된 객체를 인스턴스(Instance)라고 구분을 합니다.

의미를 부여한다면 "실행되어 메모리에 존재하는 객체" 정도라고 할 수 있습니다.

장바구니 클래스를 인스턴스화 해서 사용하는 방식의 잇점은 장바구니 인스턴스를 여러개 만들 수 있다는 것입니다.

예를 들어 장바구니 클래스라면 고객이 장바구니에 넣어서 구매하려는 일반 장바구니와는 별도로 개별 상품을 즉시 구매할 수 있는 장바구니를 따로 구분할 수 있습니다. 

또는 찜해놓기 기능용으로 장바구니 클래스를 사용할 수도 있습니다.

자바스크립트 클래스의 상속 기능을 활용하면, 이미 만든 공통의 장바구니 클래스를 상속해 기능을 추가로 확장할 수 있습니다.

장바구니 클래스를 상속해서 찜해놓기의 특화 메서드만 추가로 작성해 주면 유지 보수도 쉽고  코드 중복도 없는 좋은 장바구니 기능을 구현할 수 있습니다.

자바스크립트의 클래스는 다른 언어의 클래스에 비해 구조가 상당히 단순화되어 있습니다.

생성자 함수라는 초기화 함수가 고정으로 있고, 클래스 상속 등의 구조가 단순한 편입니다.

자바스크립트의 클래스 구조가 비교적 단순한 것은 스크립트 언어의 특성상 무거운 클래스 구조를 가져가기 힘들기 때문입니다.

다만, 클래스는 ES6에 추가된 이후 기능적인 추가나 개선은 거의 이루어지지 않고 있습니다.

함수형 언어인 자바스크립트에 객체지향 언어의 기본인 클래스 개념이 들어간다는 것도 다소 어색할 뿐더러, 함수형 구조에 익숙한 개발자들에게 큰 메리트를 주지도 못하고 있습니다.

그리고, 자바스크립트에는 클래스와 유사한 구조로 클래스 처럼 동작하는 객체 리터럴이라는 뛰어난 데이터 구조가 이미 있습니다.

고정 생성자가 없고, 상속이 안될 뿐 실제 사용에 있어서는 클래스와 크게 다를 바가 없습니다.

물론 객체 리터럴보다는 클래스가 모든 면에서 기능적으로 좋습니다.

대부분의 웹 환경에서 클래스로 구현한 체계화된 객체 구조를 쓸일이 그렇게 많지 않기 때문에 객체 리터럴만으로도 가볍게 구현해 사용하는 것이 현재의 추세입니다.

클래스 정의하기

자바스크립트의 클래스는 정형화된 틀이 정해져 있습니다.

클래스를 작성하는 구조 자체도 단순하기 때문에 구조에 맞춰서 메서드와 속성만 추가해주면 쉽게 쉽게 클래스를 만들 수 있습니다.

이해하기 쉽도록 상품 종류와 가로세로 크기 값에 따라 견적 금액을 산출하는 간단한 견젹기 클래스를 만들어보겠습니다,

1. class 클래스명 {} 으로 클래스 외형을 정의합니다.

class Estimate {}

2. 클래스 내부에 생성자(constructor) 함수를 정의합니다.

클래스 1개에 생성자는 1개만 올 수 있습니다. 필수 함수이며, function 키워드는 사용하지 않습니다.

class Estimate {   constructor(){  }}

3. 생성자에 파라메터를 추가합니다. 

여기서는 편의상 기본값 설정을 위해 상품과 가격과 크기당 단가를 가진 객체를 파라메터로 넘겨서 내부 변수에 할당합니다.

new 키워드로 클래스를 생성해 인스턴스를 estimator에 담습니다.

인자는 unifinfo 배열을 넘겨 클래스 내부의 unit에 할당합니다.

new 키워드로 클래스를 생성할 때 인스턴스 변수는 "const" 로 설정하는 것이 기본입니다.

변수로 생성했다 실수로 인스턴스를 다른 값으로 덮어쓰면 메모리 누수가 발생합니다.

생성자 안에 사용할 로컬 변수들을 정의합니다. 여기서는 파라메터로 받은 배열 정보를 로컬 변수로 설정했습니다.

ES6의 클래스에는 let unit = []; 과 같은 변수 선언을 사용할 수 없습니다.

ES6 클래스 안에는 메서드만 올 수 있습니다.

따라서 this 지시자로 클래스 안에 변수값을 대입해 동적으로 생성해야 합니다.

class Estimate {
  constructor(param){
    this.unit = param;
  }
}
let unitinfo = [{type: "wood", price: 100}, {type: "iron", price: 300}, {type: "plastic", price: 200}];
const estimator = new Estimate(unitinfo);

4. 클래스는 이미 다 만들었습니다.

메서드들을 추가해 견적가를 구해봅니다.

클래스 내부의 메서드는 function 키워드를 사용하지 않습니다.

class Estimate {
  constructor(param){
    this.unit = param;
  }
  getEstimate(unittype, width, height){
    let priceinfo = this.unit.find(item=>item.type == unittype);
    return priceinfo.price*width*height;
  }
  addUnit(unit){
    unit.push(unit);
  }
}

5. 클래스 메서드를 사용해 견적 금액을 생성해봅니다.

let unitinfo = [{type: "wood", price: 100}, {type: "iron", price: 300}, {type: "plastic", price: 200}];const estimator = new Estimate(unitinfo);
let result = estimator.getEstimate('wood', 20, 20);console.log(result);

!주의할 점

클래스 코드 작성시 일반적으로 사용하는 코딩 규칙은 다음과 같습니다. 이렇게 하지 않는다고 틀린건 아니지만, 협업을 하는 경우 이런 규칙의 준수는 코드 가독성을 높이는데 만은 도움이 됩니다.

  1. 클래스 이름 시작 문자는 대문자로 합니다.
  2. 자바스크립트의 사실상 표준인 메서드 이름 작명 규칙을 제외하고 나머지는 모두 소문자로 작성합니다.
  3. class 클래스명 { 사이는 모두 공백으로 띄워줍니다.