JS 클래스 (PurpleCode Study)

class는 객체를 정의하기 위한 상태(멤버 변수)와 메서드(함수)로 구성된다.

class Food {
  constructor(name, star) {
    this.name = name;
    this.star = star;
  }

  showStar() {
    console.log(`${this.name}의 별점은 ${this.star}점 입니다!`);
  }
}

const pasta = new Food("파스타", 5);

pasta.showStar();
//파스타의 별점은 5입니다!

new Food()를 호출하면 내부에서 정의한 메서드가 들어 있는 객체가 생성된다.

객체 기본 상태를 설정해주는 메서드 constructor()new에 의해 자동으로 호출된다.

메서드 사이엔 쉼표가 없습니다.
초보 개발자는 클래스 메서드 사이에 쉼표를 넣는 실수를 저지르곤 합니다. 쉼표를 넣으면 문법 에러가 발생합니다.

클래스란?

  • 자바스크립트에서 클래스는 함수의 한 종류이다.

    console.log(typeof Food);//function

  • class Food{..} 문법 구조가 하는일은 다음과 같다.

    1. Food라는 이름을 가진 함수를 만든다.

    함수 본문은 생성자 메서드 constructor에서 가져온다.

    생성자 메서드가 없으면 본문이 비워진 채로 함수가 만들어 진다.

    2. showStar같은 메서드를 User.prototype에 저장한다.

    new Food를 호출해 객체를 만들고, 객체의 메서드를 호출하면 메서드를 프로토타입에서 가져온다.

그냥 함수를 사용해도 클래스 역할을 하는 함수를 만들어 줄 수 있다.

function Food(name, star) {
  this.name = name;
  this.star = star;
}

Food.prototype.showStar = function () {
  console.log(`${this.name}의 별점은 ${this.star}점 입니다!`);
};

let food = new Food("떡볶이", 5);

food.showStar();

class를 사용할 때와 결과가 거의 같다.

하지만 이 두방법의 중요한 차이점이 있다.

  1. class로 만든 함수엔 특수 내부 프로퍼티인 [[FunctionKind]]:"classConstructor"가 붙는다.

    자바스크립트는 다양한 방법을 사용해 함수에 [[FunctionKind]]:"classConstructor"가 있는지 확인한다.

이런 검증 과정이 있기 때문에 클래스 생성자를 new와 함께 호출하지 않으면 에러가 발생한다.

  1. 클래스 메서드는 열거할 수 없다.
    클래스 prototype 프로퍼티에 추가된 메서드 전체의 enumerable 플래그는 false 이다.
class Student(name,age) {
    constructor{
        this.name = name;
        this.age = age;
    }

    getName(){
        console.log(`이름은 ${this.name} 입니다`)
    }
    getAge(){
        console.log(`나이는 ${this.age} 입니다`)
    }
}

for(let f in Student.prototype){
    console.log(f); // 클래스 내부 메소드 열거 안됨
}
  1. 클래스는 항상 엄격 모드로 실행된다.

클래스 표현식

  • 함수처럼 클래스도 다른 표현식 내부에서 정의, 전달, 반환, 할당할 수 있다.
//클래스 이름을 붙이면, 이 이름은 오직 클래스 내부에서만 사용 가능
let Food = class {
  descClass() {
    console.log("food class");
  }
};

new Food().descClass();
//food class
  • 클래스를 동적으로 생성하는 것도 가능하다.
function makeStudent(name) {
  return class {
    getName() {
      console.log(name);
    }
  };
}

//새로운 클래스를 만듦
let Student = makeStudent("김지원");

new Student().getName();//김지원

getter, setter

  • 클래스도 gettersetter를 포함할 수 있다.
class Food {
  constructor(name, star) {
    this._name = name;
    this._star = star;
  }
  get name() {
    return this._name;
  }
  set name(value) {
    this._name = value;
  }
  get star() {
    return `${this._name}의 별점은 ${this._star}`;
  }
  set star(value) {
    if (value <= 0) {
      console.log("별점은 1점 이상이여야 합니다.");
      return;
    }
    this._star = value;
  }
}

let pasta = new Food("파스타", 0);

console.log(pasta.star); //파스타의 별점은 0

pasta.star = 0; //별점은 1점 이상이여야 합니다.

클래스 필드

(근래에 더해진 기능이다.)

  • 클래스 필드라는 문법을 사용하면 어떤 종류의 프로퍼티도 클래스에 추가할 수 있다.

  • 클래스를 정의할 때 프로퍼티이름 = 값을 써줘 간단하게 클래스 필드를 만들 수 있다.

  • 클래스 필드의 중요한 특징 중 하나는 User.prototype이 아닌 개별 객체에만 클래스 필드가 설정된다는 점이다.

class Dog {
  name="쪼꼬";

  bark() {
    console.log(`${this.name}는 멍멍`);
  }
}

new Dog().bark(); //쪼꼬는 멍멍

let dog = new Dog();
console.log(dog.name);//쪼꼬
console.log(dog.prototype.name);//undefined

클래스 상속

  • 클래스를 다른 클래스로 확장 가능하다.
  • 상속을 할때는 extends 키워드를 사용하게 된다.
  • 상속을 받을 때 메서드, 생성자 오버라이딩이 가능하다.
  • super키워드 사용
class Car {
  constructor(type) {
    this.type = type;
  }

  drive() {
    console.log("drive 기능");
  }
}

class Bus extends Car {
  constructor(type, color) {
    //상속 클래스의 생성자에선 super를 호출해 부모 생성자를 실행해 주어야 한다.
    super(type);
    this.color = color;
  }
  myColor() {
    console.log(this.color);
  }
  drive() {
    super.drive();
    this.myColor();
  }
}

let bus = new Bus("버스", "green");

bus.myColor(); //green
bus.drive(); //drive 기능 green (method overriding)
console.log(bus.type); //버스
console.log(bus.color); //green

정적 메서드와 정적 프로퍼티

  • prototype이 아닌 클래스 함수 자체에 메서드를 설정할 수 있다.
  • 이런 메서드를 정적 메서드라고 부른다.
  • 정적 메서드는 static 키워드를 붙여 만들 수 있다.
  • 정적 프로퍼티도 사용가능하다.
class Menu {
    //정적 프로퍼티
    static name = "야채곱창"
    //정적 메서드
    static showMenu{
        console.log(this.name);
    }
}

Menu.showMenu();
console.log(Menu.name);

instanceof로 클래스 확인하기

  • instanceof 연산자를 사용하면 객체가 특정 클래스에 속하는지 아닌지를 확인 할 수 있다.
  • 생성자 함수에서도 사용할 수 있다.

문법
obj instanceof Class;

objclass에 속하거나 class를 상속받는 클래스에 속하면 true가 반환된다.

function Menu(){}

console.log(new Menu() instance of Menu);//true

Array같은 내장 클래스에서도 사용이 가능하다.

let arr = [1,2,3,4,5];

console.log(arr instanceof Array); //true
console.log(arr instanceof Object); //true

arrObject에도 속한다는 것에 주목하면 된다.

이유는 Array는 프로토타입 기반으로 Object를 상속받기 때문이다.

좋은 웹페이지 즐겨찾기