JS NORMAL | 클래스

chaen·2024년 1월 24일
0

JS Grammar

목록 보기
18/28
post-thumbnail

❓ 클래스(Class)란?

  • 더 객체 지향적으로 표현하기 위해 ES6에 새롭게 추가된 문법
  • 프로토타입 방식으로 작동되며, 문법 생김새는 다르지만 내부 로직은 완전히 같다.
  • 객체를 직접 작성하여 정의하고 생성할 수 있지만, 그보다 더 쉽고 간단하게 작성하기 위해 제안된 문법
  • 객체를 생성하기 위한 틀이다.

객체와 인스턴스

대부분의 개발자들은 객체(object)와 인스턴스(instance)를 혼용해서 사용한다. 두 용어는 비슷하지만, 미세한 차이가 있다.

집을 만든다고 가정할 때, 설계도를 작성하고 해당 설계도를 기반으로 똑같은 집을 만들게 된다. 각각의 집(객체)은 모두 똑같기 때문에 어떠한 집 하나를 가리켜 부르기 위해선 각 집에 고유한 표시가 필요하다. 이때 각각의 집을 인스턴스라고 부른다.

클래스: 붕어빵 기계 / 사람의 기본 구조 / 설계도
객체: 붕어빵 / 사람 / 푸르지오 아파트들
인스턴스: 붕어빵 1, 2.. / 영희, 철수, 민수.. / 101동, 102동, 103동..

💻 클래스 선언

  • 우선 필드 선언이 필요하다.
  • 필드란 이 클래스가 생성할 객체가 갖는 프로퍼티이다.
  • 앞으로 해당 클래스를 사용하는 객체는 모두 아래의 프로퍼티를 물려 받게 된다.
class Student {
  // 필드
  name;
  age;
  grade;
}
  • 그 다음으로는 생성자(constructor)을 선언한다.
  • 생성자는 특수한 메서드로 실질적으로 객체를 생성하는 함수이다.
class Student {
  name;
  age;
  grade;

  // 생성자
  constructor(name, grade, age) {
    this.name = name;
    this.grade = grade;
    this.age = age;
  }
}
  • 생성자에서는 매개변수로 프로퍼티 값을 받아 this.프로퍼티의 값으로 할당한다.
  • this는 객체이며 현재 만들고 있는 객체를 의미한다.
  • 따라서 이 생성자 메서드는 현재 만들고 있는 객체의 각 프로퍼티의 값을 매개변수로 전달받은 값으로 설정하는 역할을 한다.
const studentB = new Student("홍길동", "A+", 27);
console.log(studentB); // Student { name: '홍길동', age: 27, grade: 'A+' }
  • 클래스를 이용해 새로운 객체를 생성할 때에는 new 클래스이름 형태로 클래스의 생성자 함수를 호출한다.
  • 인수로는 각각 name, grade, age를 전달한다.

주의 할 점

  • 클래스명의 첫 글자는 대문자여야 한다.
  • constructor는 한 개만 존재해야 한다.

💻 클래스 메소드 정의

class Student {
  name;
  grade;
  age;
  constructor(name, grade, age) {
    this.name = name;
    this.grade = grade;
    this.age = age;
  }

  // 메서드
  study() {
    console.log("열심히 공부 함");
  }
  introduce() {
    console.log(`안녕하세요!`);
  }
}

let studentB = new Student("홍길동", "A+", 27);

studentB.study(); // 열심히 공부 함
studentB.introduce(); // 안녕하세요!

아래와 같이 클래스의 메소드 이름을 정하고 표현식을 대괄호로 감싸서 사용할 수도 있다.

const study = '열심히 공부 함';

class Person {
  constructor(name, grade, age) { ... }
  [study]() { ... }
}

console.log(new Person({name: "홍길동", grade: "A+", age: 27}).study());

Getter / Setter

Getter: 객체의 속성(property) 값을 반환하는 메서드
Setter: 객체의 속성 값을 설정, 변경하는 메서드

일반적으로 아래처럼 직접 속성에 접근할 수 있지만,

const user = { height: '180cm', weight: '50kg' };
console.log(user.height);
user.weight = '52kg';

getHeight(), setWeight() 을 통해 간접 접근하는 방식이 있다.

const user = {
  height: '180cm',
  weight: '50kg',
  
  getHeight() {
    return user.height;
  },
  setWeight(value) {
    user.weight = value;
  }
};

console.log(user.getHeight()); // 호출해야 함
user.setWeight('52kg');
  • ES6 자바스크립트부터는 GetterSetter를 간단하게 정의할 수 있는 문법이 별도로 추가되었다.
  • 프로퍼티 명 왼쪽에 get, set 키워드만 붙이면 알아서 Getter, Setter 로 인식한다.

🛡️ GetterSetter를 사용하는 이유

  • 객체 내부 속성에 직접 접근하지 않아 정보 은닉 가능
  • 코드의 안전성과 유지보수성 향상
  • 값을 설정할 때 유효성 검증(조건문 필터링 등) 가능

✅ Getter를 사용하는 경우 (with private field)

class Person {
  #name;

  constructor(name) {
    this.#name = name;
  }

  get getName() {
    return this.#name;
  }

  introduce() {
    return `안녕하세요, ${this.getName}`;
  }
}

const person1 = new Person('홍길동');

console.log(person1.#name); // ❌ SyntaxError — private 직접 접근 불가
console.log(person1.getName);  // ✅ 홍길동 — getter로 접근
console.log(person1.introduce()); // 안녕하세요, 홍길동씨

✅ Getter 없이 public 속성 사용하는 경우

class Person {
  constructor(name) {
    this.name = name; // public
  }
  
  introduce() {
    return `안녕하세요, ${this.name}`; // name 속성에 직접 접근
  }
}

const person1 = new Person('홍길동');
console.log(person1.name);  // 홍길동
person1.name = '김철수';// 외부에서 직접 name에 값을 할당 가능
console.log(person1.introduce()); //안녕하세요, 김철수씨

정적 메서드 (static)

  • 객체로 접근할 수 없으며, 클래스 명으로만 접근 가능하다.
  • 프로퍼티와 메소드 앞에 static을 붙여준다.
  • 정적 프로퍼티 : 인스턴스가 사용할 수 없는 프로퍼티
  • 정적 메소드 : 인스턴스가 사용할 수 없는 함수
class Person {
  // 정적 프로퍼티
  static interests = ["music","exercise"];

  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  // 정적 메소드
  static interestWrite() {
    console.log(Person.interests[0]);
  }
}

let person1 = new Person({name: '홍길동', age: 21});
person1.interestWrite(); //TypeError
Person.interestWrite(); //music

💻 Private 클래스 변수

이전까지 자바스크립트 클래스의 모든 메서드는 퍼블릭으로만 지정되었지만, ES2021부터는 프라이빗 메서드와 필드 정의가 가능해졌다.

Private Property

  • 외부에서 접근 불가능 / Class 안에서만 수정
  • 변수 앞에 #을 붙임 (혹은 _를 붙이나 최근에는 #를 주로 사용)
class Num {
  // private 변수
  #num = 100;
  
  // private 메서드
  #privateMethod(){
    console.log(this.#num);
  }
}

let num1 = new Num();
num1.privateMethod //undefined

💻 클래스 상속

클래스 상속(class inheritance, subclassing) 기능을 통해 한 클래스의 기능을 다른 클래스에서 재사용할 수 있다.

두 관계는 Parent - Child 혹은 Super - Sub 라고 지칭한다.

class Parent { ...}
class Child extends Parent { ... }
  • 상속을 하게 되면 아래와 같이 중복을 줄이고 코드를 작성할 수 있다.
  • 대신, 지우는 과정에서 매개변수는 그대로 둔 채 super을 통해 상속받아야 한다.
  • super은 부모 클래스의 생성자를 호출한다.
class Student {
  name;
  grade;
  age;
  
  constructor(name, age) {
    this.name = name;
    this.grade = grade;
    this.age = age;
  }
  study() {
    console.log("열심히 공부 함");
  }
  introduce() {
    console.log(`안녕하세요!`);
  }
}

class Transfer extends Student {
  favoriteSkill;
  
  constructor (name, grade, age, favoriteSkill) {
    super(name, grade, age);
    this.favoriteSkill = favoriteSkill;
  }
  
  programming() {
    console.log(`${this.favoriteSkill}로 프로그래밍함`);
  }
}

const transferStudent = new Transfer("홍길동", "A+", 27, "JavaScript");

// 부모의 static요소를 상속
console.log(transferStudent); {"홍길동", "A+", 27, "JavaScript"}
transferStudent.programming(); //JavaScript로 프로그래밍함


참고: 자바스크립트 클래스 문법 - 완벽 가이드
13편. 객체와 클래스
자바스크립트의 클래스 소개

0개의 댓글