[F-Lab 모각코 챌린지 64일차] JavaScript 클래스 Class

Nami·2023년 8월 3일
0

66일 포스팅 챌린지

목록 보기
64/66

JavaScript 클래스 Class

객체 지향 프로그래밍(OOP)에서 사용되는 템플릿 (청사진, 틀).
관련된 속성과 메서드를 그룹화하는 기능을 제공하는 문법적 구조.

  • ES6(ES2015)이후 부터 JavaScript에서 클래스를 공식적으로 지원함.
  • 기존의 프로토타입 기반 상속을 보다 명확하고 편리하게 구현할 수 있게 되었다.
  • 생성자 함수 대신 많이 사용, Typescript도 클래스 기반.
  • 클래스는 생성자(constructor)와 메서드(method)를 포함한다.

생성자 constructor

객체(인스턴스)를 생성할 때 호출되는 특별한 메서드다.
클래스 내부에 constructor 키워드를 사용하여 정의하고, 객체를 초기화하는 데에 사용된다.

class ClassName {
  constructor(/* constructor parameters */) {
    // constructor (생성자)는 객체가 생성될 때 호출된다.
    // 객체를 초기화하는 데 사용된다.
  }

  method1(/* parameters */) {
    // 메서드 1
  }

  method2(/* parameters */) {
    // 메서드 2
  }

  // 추가적인 메서드 등을 정의할 수 있다.
}

생성자는 클래스가 new 키워드를 사용하여 인스턴스화될 때 자동으로 호출된다.
이때 인자를 전달하여 객체를 초기화하는 데에 사용된다.
생성자 내에서 this 키워드를 사용하여 클래스의 속성을 설정할 수 있다.

// 클래스를 사용하여 객체를 생성하는 방법
const obj = new ClassName(/* constructor arguments */);
/* 

객체를 손쉽게 만들 수 있는 템플릿
1. 생성자 함수 (고전적 방법)
2. 클래스 🌟

*/

// 클래스 Class
class User {
  // 생성자 new 키워드로 객체를 생성할 때 호출되는 함수
  constructor(name, emoji) {
    this.name = name;
    this.emoji = emoji;
  }
  display = () => {
    console.log(`${this.name}: ${this.emoji}`);
  };
}

// nami는 User 클래스의 인스턴스이다.
const nami = new User('Nami', '🤓');
// james는 User 클래스의 인스턴스이다.
const james = new User('James', '🥸');

console.log(nami);
console.log(james);
// User 클래스가 인스턴스화될 때 name, emoji라는 두 개의 속성을 객체에 할당한다.
// 각 객체는 생성자에 전달된 인자를 사용하여 name, emoji 속성을 초기화한다.
// 생성자는 클래스의 인스턴스 생성 시점에 한 번만 호출되므로, 객체를 초기화하거나 설정하는 데 사용되는 코드를 포함할 수 있다. 

// obj는 객체이고, 그 어떤 클래스의 인스턴스도 아니다.
const obj = { name: 'sangsu' };

정적 프로퍼티 Static Property

클래스 자체에 속하는 프로퍼티, 클래스의 인스턴스와는 독립적으로 동작한다.
즉, 클래스의 모든 인스턴스들이 공유하는 속성!
정적 프로퍼티는 클래스 메서드 내에서 사용될 수도 있다.

// static 정적 프로퍼티
class newUser {
  static MAX_USERS = 10;
  constructor(name, emoji) {
    this.name = name;
    this.emoji = emoji;
  }
  // 클래스 레벨의 정적 메서드 🔽
  static makeRandomUser() {
    // 클래스 레벨의 메서드에서는 this를 참조할 수 없음
    return new newUser('Cheolsu', '😎');
  }
  // 인스턴스 레벨의 메서드 🔽
  display = () => {
    console.log(`${this.name}: ${this.emoji}`);
  };
}
const cheolsu = newUser.makeRandomUser();
console.log(cheolsu);
console.log(newUser.MAX_USERS);
// 클래스 레벨의 함수는 클래스 이름으로 접근 가능하다.
  • 정적 프로퍼티는 클래스 자체에 속하므로 인스턴스 생성 없이 클래스 이름을 통해 직접 접근하고 사용할 수 있다.
  • 정적 프로퍼티를 사용하면 클래스 내에서 객체 간에 공유되어야 하는 데이터를 쉽게 관리할 수 있다.

접근 제어자

클래스의 속성과 메서드에 대한 접근 수준을 제어하는 기능을 제공한다. 이를 통해 클래스 내부의 멤버들이 외부에서 어떻게 접근될 수 있는지를 조절할 수 있다.

클래스 접근 제어자를 사용하여 클래스 멤버들의 접근 범위를 관리하면, 데이터 은닉과 캡슐화를 통해 더 안정적이고 유지보수가 용이한 코드를 작성할 수 있다.

  • public(default)
    클래스 멤버들에 대한 접근 수준을 제한하지 않는다.즉, 어디서든 클래스 외부에서 접근 가능
  • private
    # 기호를 사용하여 클래스 내부에서만 접근 가능한 멤버를 나타낸다. 외부에서 직접 접근하거나 변경할 수 없다.
  • protected
    _ (언더스코어) 기호를 사용하여 상속받은 자식 클래스에서 접근 가능한 멤버를 나타낸다.
// field
// 접근제어자 - 캡슐화
class Member {
  name;
  emoji;
  #type = '일반회원';
  constructor(name, emoji) {
    this.name = name;
    this.emoji = emoji;
  }
  display = () => {
    console.log(`${this.name}: ${this.emoji}`);
  };
}

const kdong = new Member('kdonge', '😛');
console.log(kdong);

접근자 프로퍼티 Accessor Property

Getter

getter는 클래스 내의 속성 값을 읽을 때 사용된다.
getter를 정의하려면 속성 앞에 get 키워드를 사용하고, 해당 속성 이름에 맞는 메서드를 정의
getter는 마치 속성처럼 사용되며, 객체.속성 형식으로 접근할 때 해당 메서드가 호출된다.

class Example {
  constructor() {
    this._value = 42;
  }

  get myValue() {
    return this._value;
  }
}

const obj = new Example();
console.log(obj.myValue); // 출력: 42

Setter

setter는 클래스 내의 속성 값을 수정할 때 사용된다.
setter를 정의하려면 속성 앞에 set 키워드를 사용하고, 해당 속성 이름에 맞는 메서드를 정의한다.
정의된 setter는 마치 속성처럼 사용되며, 객체.속성 = 값 형식으로 값을 할당할 때 해당 메서드가 호출된다.

class Example {
  constructor() {
    this._value = 0;
  }

  set myValue(newValue) {
    if (newValue >= 0) {
      this._value = newValue;
    } else {
      console.log("Invalid value. Value must be non-negative.");
    }
  }
}

const obj = new Example();
obj.myValue = 42; // setter 호출
console.log(obj.myValue); // 출력: 42

obj.myValue = -10; // setter 호출, 출력: Invalid value. Value must be non-negative.
class Mentee {
  constructor(fullName, course, mentor) {
    this.fullName = fullName;
    this.course = course;
    this.mentor = mentor;
  }
  get info() {
    return `${this.fullName} 님은 ${this.course} 과정, ${this.mentor} 멘토님과 매칭되었습니다.`;
  }
  set info(value) {
    console.log('set', value);
  }
}

const mentee = new Mentee('나미', '프론트엔드', '아네르스 하일스베르');
mentee.fullName = '남희';
console.log(mentee);
console.log(mentee.fullName);
console.log(mentee.info);
mentee.info = '성공';
  • gettersetter는 데이터를 보호하고 속성에 접근을 제어하는 데 유용하다.
  • 일반적으로 getter를 사용하면 속성을 읽을 때 추가적인 계산을 수행하거나 데이터의 유효성을 검사할 수 있다.
  • setter를 사용하면 속성에 값을 할당할 때 유효성을 검사하거나 다른 속성에 영향을 미칠 수 있다.

상속, 확장

  • 객체 지향 프로그래밍(OOP)에서 중요한 개념
  • 이미 정의된 클래스의 속성과 메서드를 다른 클래스가 상속받는 것을 의미
  • 재사용성과 확장성을 증가
  • 자식 클래스는 부모 클래스의 모든 속성과 메서드를 상속받고, 자신의 추가적인 속성과 메서드를 정의할 수도 있다.
  • ES6(ES2015)에서 도입된 extends 키워드를 사용하여 구현
class Parent {
  constructor(/* constructor parameters */) {
    // 부모 클래스의 생성자
  }

  parentMethod() {
    // 부모 클래스의 메서드
  }
}

class Child extends Parent {
  constructor(/* constructor parameters */) {
    super(/* arguments to pass to parent constructor */);
    // 자식 클래스의 생성자
  }

  childMethod() {
    // 자식 클래스의 메서드
  }
}
class Pokemon {
  constructor(action) {
    this.action = action;
  }
  attack() {
    console.log('필살기가 아직 없어.');
  }
  live() {
    console.log('디지몬 월드에서 살고있어.');
  }
}

class Agumon extends Pokemon {
  // 오버라이딩 overriding
  attack() {
    console.log('필살기 : 꼬마불꽃 🔥🔥🔥🔥🔥');
  }
  eat() {
    console.log('우걱우걱(アグアグ)');
  }
}
const agumon = new Agumon('코로몬에서 진화했어.');
console.log(agumon);
agumon.attack();
agumon.live();

class Coromon extends Pokemon {
  constructor(live, owner) {
    super(live);
    this.owner = owner;
  }
  // 오버라이딩 overriding
  attack() {
    console.log('필살기 : 거품 🫧🫧🫧🫧🫧🫧');
  }
  move() {
    console.log('데굴데굴(ころころ)');
  }
}

const coromon = new Coromon('깜몬에서 진화했어.', '태일이');
console.log(coromon);
coromon.attack();
coromon.live();

객체 클래스를 알아보았다. 테스트 코드로 테스트 해볼 수 있을 것 같아 해보려한다!


  • 드림코딩아카데미 | Javascript 마스터리 (ES6+)🎦
  • ChatGPT 🤖

0개의 댓글