[TIL # 22] JS 9일차

Yejin Yang·2022년 5월 3일
0

[TIL]

목록 보기
22/67
post-thumbnail

Class

  • Class는 객체를 생성하기 위한 템플릿이다.
  • Class를 사용하는 가장 큰 이유는 재사용성이다.
  • 붕어빵을 만들 때 사용하는 붕어빵 틀이라고 생각하면 쉽다.
  • 연관있는 데이터들을 한데 모으는 컨테이너 역할을 한다.

Class 구성

객체의 상태를 나타내는 필드(field)
객체의 행동을 나타내는 메소드(method)

간혹, 필드(field)만들어있고 메소드(method)는 없는 class가 있는데 데이터=필드만 들어있는걸 데이터 클래스라고 부른다.

class 선언

쉽게 class를 선언해주면 class 객체를 만들 수 있다.

// 클래스 문법
class Hello {
	constructor(str) {
	this.msg = str // 일반함수 
}
getMsg() {
	return this.msg
 }
}

// 오브젝트, 생성시 new키워드 사용
// constructor에서 전달
const res1 = new Hello('팥')
console.log(res1)

const res2 = new Hello('슈크림') // 넣는 데이터에 따라 다른 객체
console.log(res2)

console.log(res1.getMsg === res2.getMsg)
  • 붕어빵이라는 틀(res)는 같지만 넣는 데이터에 따라 다른 객체가 만들어진다.
  • class(붕어빵 틀)를 이용해서 새로운 인스턴스를 생성하면 object가 된다(팥붕, 슈붕)
    • class는 정의만 한 것이라 실제로 메모리에는 올라가진 않지만 object는 메모리에 올라가있음
  • 클래스에는 일반함수로 만들어야 상황에 맞게 달라지면서 원하는 클래스가 될 수 있다. 화살표 함수 X
  • 클래스 선언은 let과 const처럼 블록 스코프에 선언되며, 호이스팅(hoisting)이 일어나지 않는다.

Class 몸체에 정의할 수 있는 메소드

클래스 몸체(class body)에는 메소드만 선언할 수 있다. 클래스 바디에 클래스 필드(멤버 변수)를 선언하면 문법 에러(SyntaxError)가 발생한다.

  1. constructor(생성자)
  2. 프로토타입 메소드
  3. 정적 메소드

1. constructor(생성자)

  • constructor는 인스턴스를 생성하고 초기화하기 위한 특수한 메소드
  • 클래스 필드의 선언과 초기화는 반드시 constructor 내부에서 실시
  • constructor를 사용해서 나중에 오브젝트를 만들 때 필요한 데이터를 전달.
class Hello {
  name = ''; // SyntaxError

  constructor() {}
}

Getter & Setter

클래스를 사용하는 사용자가 잘못 사용해도 우리가 조금 더 방어적인 자세로 만들 수 있는 것이 Getter & Setter이다.

get이라는 키워드로 값을 리턴하고
set이라는 키워드로 값을 설정할 수 있다.
대신 set은 값을 설정 하기에 value를 받아와야한다.

class User {
  constructor(firstName, lastName, age) {
    this.firstName = firstName;
    this.lastName = age;
    this.age = age;
  }

  get age() {
    return this._age;
  }

  set age(value) {
    this._age = value < 0 ? 0 : value;
  }
}

const user1 = new User("스티브", "잡스", -1);
console.log(user1.firstName);

constructor에서 정의한 age와, getter와 setter안에서 사용하는 변수를 다른 이름으로 설정해야한다. 그 이유는 setter안에서 전달 된 value를 this.age에 할당할 때 메모리의 값을 업데이트 하는 것이 아니라 setter를 계속 무한 반복하며 호출 -> call stack이 초과 에러 발생한다.
통상 _언더바 기호를 앞에 추가로 써줘서 getter와 setter안에 변수를 선언한다.

정적 메소드(Static properties and methods)

Object에 data에 상관없이 공통적으로 클래스에서 사용할 수 있는 것이라면 static과 staticMethod를 사용하는 것이 메모리의 사용을 조금 더 줄여줄 수 있다.

class Article {
  static publisher = "Dream Coding";
  constructor(articleNumber) {
    this.articleNumber = articleNumber;
  }

  static printPublisher() {
    console.log(Article.publisher);
  }
}

const article1 = new Article(1);
const article2 = new Article(2);
console.log(Article.publisher);
Article.printPublisher();

오브젝트, 데이터에 상관없이 클래스가 가지고 있는 고유한 값과, 데이터에 상관없이 동일하게 반복적으로 사용되어지는 method가 있을 수 있다. 그런것들은 static이라는 키워드를 사용해서 만들면 오브젝트에 상관없이 클래스 자체에 연결되어진다.

상속(extends)

class에서 상속 개념을 이용할 수 있다. 상속을 이용하면 기존의 class의 값을 모두 접근하여 사용할 수 있다. 재사용의 장점이 있다.
상속은 extends를 사용한다.

class Shape {
  constructor(width, height, color) {
    this.width = width;
    this.height = height;
    this.color = color;
  }

  draw() {
    console.log(`drawing ${this.color} color!`);
  }

  getArea() {
    return this.width * this.height;
  }
}

// extends라는 키워드로 Shape 재사용
class Rectangle extends Shape {}
class Triangle extends Shape {
  draw() {
  // super는 공통적으로 정의한 것도 호출하 게 됨
    super.draw();
    console.log("🔺"); // overriding
  }
  // 필요한 함수만 overriding
  getArea() {
    return (this.width * this.height) / 2;
  }
}

const rectangle = new Rectangle(20, 20, "blue");
rectangle.draw();
console.log(rectangle.getArea());

const triangle = new Triangle(20, 20, "red");
triangle.draw();
console.log(triangle.getArea());

console.log(rectangle instanceof Rectangle);
console.log(triangle instanceof Rectangle);
console.log(triangle instanceof Triangle);
console.log(triangle instanceof Shape);
console.log(triangle instanceof Object);
console.log(triangle.toString()); // 재정의 가능
profile
Frontend developer

0개의 댓글