본문 바로가기
Javascript

6. [JavaScript] 클래스

by 뽀롱트옌드 2023. 7. 27.

🏃🏻‍♀️ class

[ 프로토 타입 ]

  • prototype
  • 자바스크립트는 prototype(이웅모 선생님 블로그 - prototype) 기반
  • 자바스크립트의 모든 객체와 배열은 상위 객체와 연결되어 상위 객체의 속성과 메소드를 상속(공유)되어 사용할수있음 이때 상위 객체를 프로토타입이라고 함
  • 최상위 배열, 객체에 내장되어있는 메소드(MDN - 배열 내장 메소드)나 프로토타입(.prototype)으로 새로 등록하는 함수(.함수명 = function() {})를 prototype메소드(prototype속성)이라고 함
    • 함수안에 this를 사용 할 경우 fucntion키워드를 사용하는 일반함수로 등록
      -> 화살표함수의 this는 정의가 다르기때문
    • 프로토타입메소드는 인스턴스에서만 사용가능
  • 생성자함수로 실행이되서 호출(class, 객체라고도 함)해서 반환되어 나온 결과물(인자로 들어간 배열의 아이템, 객체안의 데이터가 담긴 변수)이 인스턴스(instance)
    • 인스턴스: 생성자 함수(new)로 반환되는 결과물
  1. 생성자함수로 배열을 만들고 프로토타입 메소드 등록하기
// 배열생성
const colors = new Array('Pink', 'Yellow', 'White'); // colors -> 인스턴스
console.log(colors); // (3) ['Pink', 'Yellow', 'White'] 

// 배열에 내장되어있는 프로토타입 메소드 length
console.log(colors.length); // 3

// 배열데이터에 프로토메소드 직접 등록 
Array.prototype.itMe = function() {
  console.log(`0. ${this[0]}, 1. ${this[1]}, 2. ${this[2]}`);
}

colors.itMe(); // 0. Pink, 1. Yellow, 2. White

// 최상위 배열 데이터 Array에 등록했기때문에 다른 배열에도 상속이되어 사용 가능
const snacks = ['Candy', 'jelly'];
snacks.itMe(); // 0. Candy, 1. jelly, 2. undefined
  1. 함수로 객체 구조를 만들고 메소드 등록후 생성자함수로 객체 생성
    • 생성자함수로쓰일 함수와 생성자함수 사용시 파스칼케이스로 작성
// 함수로 객체 구조 생성
function Colors(first, last) {
  this.firstColor = first // firstColor속성에 매개변수 first로 받은 데이터 할당
  this.lastColor = last
}

// new Colors로 생성한 모든 객체에서 사용할수있는 프로토메소드 등록
Colors.prototype.getAllColor = function() {
    return `springColors -> ${this.firstColor}, ${this.lastColor}`
}

// 생성자함수 new Colors() 로 객체 생성 
const spring = new Colors('Yellow', 'Orange'); // spring -> 인스턴스

console.log(spring); //Colors {firstColor: 'Yellow', lastColot: 'Orange'}
console.log(spring.getAllColor()); // springColors -> Yellow, Orange

[ class ]

  • prototype을 내장하여 새로문 문법으로 구현되어 ES6(2015ver)부터 도입됨

- 기본문법

  • 현문서 [프로토 타입]2.예제에 프로퍼티(속성)를 추가해 class 문법으로 변경
// 클래스 정의
class Colors {
  constructor(season, first, last) {
    // 객체 구조 생성
    this.season = season; // season속성에 매개변수season으로 받은 데이터 할당
    this.firstColor = first;
    this.lastColor = last;
  } // 쉼표없음
  // 프로토타입메소드 생성
  getSeasonColor() {
    // new Colors(인자, 인자, 인자)로 생성한 모든 클래스에서 사용할수있는 메소드등록
    return `${this.season} Colors -> ${this.firstColor}, ${this.lastColor}`;
  }
}

const spring = new Colors("Spring", "Yellow", "Orange"); // spring는 Colors클래스의 인스턴스

//  인스턴스에 클래스에서 생성한 프로토타입메소드 호출
console.log(spring.getSeasonColor()); // Spring Colors -> Yellow, Orange

- get, set

get(조회), set(지정) 키워드를 사용하는 메서드 -> 속성처럼 사용가능함

class Color {
  constructor(season, color) {
    this.curiousSeason = season
    this.whatColor = color
  }

  // Getter 메소드
  get seasonColor () {
    return `${this.curiousSeason} Color -> ${this.whatColor}`
  }

  // Setter 메소드
      set seasonColor(value) {
      [this.curiousSeason, this.whatColor] = value.split(' ');
  }
}

const seasonSummer = new Color('Summer', 'Blue'); // seasonSummer는 Color클래스의 인스턴스

console.log(seasonSummer); // Color {curiousSeason: 'Summer', whatColor: 'Blue'}
  • Getter
    값을 얻는 메소드
    메서드를 .(점표기법)을 사용해 속성처럼 조회하면 getter메서드가 호출되어 값을 얻어옴
// Getter메소드로 값을 조회
console.log(seasonSummer.seasonColor); // Summer Color -> Blue
seasonSummer.whatColor = 'white'; // 객체 속성에 값재할당
console.log(seasonSummer.seasonColor); // Summer Color -> White
  • Setter
    값을 지정하는 메소드
    메서드를 =(할당연산자)를 사용해 속성처럼 데이터를 할당하면 setter메서드가 호출되어 값을 할당함
// Setter메소드로 여러 객체에 값을 재할당
seasonSummer.seasonColor = 'Fall Red';
console.log(seasonSummer.seasonColor); // Fall Color -> Red

- 정적 메소드

  • Static method: 메소드 앞에 static키워드를 붙임
  • static 메소드명() {}
  • 클래스자체에서 호출가능한 메소드 (인스턴스에서는 호출 안됨)
    • 프로토타입 메소드는 인스턴스에는 사용가능하나 클래스에 직접적으로 사용(호출)못함
  • 정적메소드는 객체(인스턴스)의 구조가 정의된 클래스구조와 맞는지 확인하는 보조역할
class Color {
  constructor(season, color) {
    this.curiousSeason = season;
    this.whatColor = color;
  }
  // 인스턴스에서 호출가능한 프로토타입메소드 생성
  seasonColor() {
    return `${this.curiousSeason} Color -> ${this.whatColor}`;
  }
  // 클래스자체에서도 호출가능한 정적메소드 생성
  static isSeasonColor(object) {
    if (object.curiousSeason && object.whatColor) {
      return true
    }
    return false
  }
}

const seasonSummer = new Color('Summer', 'Blue');
const seasonAutumn = {
  food: 'Apple',
  month: 10
}

// 인스턴스(객체)에 프로토타입메소드 호출
console.log(seasonSummer.seasonColor()); // Color {curiousSeason: 'Summer', whatColor: 'Blue'}
// 클래스에 정적메소드 호출 -> 클래스와객체의 구조가 같인지 확인
console.log(Color.isSeasonColor(seasonSummer)); // true
console.log(Color.isSeasonColor(seasonAutumn)); // false

// 정적메소드는 인스턴스에서 호출안됨
console.log(seasonSummer.isSeasonColor()); //  Uncaught TypeError: seasonSummer.isSeasonColor is not a function
// 프로토타입메소드는 class에서 호출안됨
console.log(Color.seasonColor()); // Uncaught TypeError: Color.seasonColor is not a function 

- class의 기능들

  • 상속
    extends키워드와 sper()가 짝꿍
    부모(조상)클래스의 로직을 상속(공유) 받음
    • 기본문법
class 정의할클래스명 extends 상속(확장)할클래스명 {
    constructor(현재정의할클래스에서사용할매개변수들, 상속하는클래스에서사용할매개변수들){
      sper(상속할클래스에서 사용할 매개변수)
      this.속성명 = 값
    }
}

< 내가 만든 예제 >


// 조상 class
class Food {
  constructor(weight = 10) {
    this.weight = weight
    this.price = weight * 100 
    this.type = '과일'
  }
  raise() {
    this.price *= this.weight
  }
  sale() {
    if (this.price <= 1000) {
      console.error(`${this.type}사세요 세일함미다!!!`);
      return
    }
    this.price -= this.weight

  }
}

const food = new Food(5); // 생성자함수로 객체(food 인스턴스)생성
console.log(food); // Food {weight: 5, price: 500, type: '과일'}
food.sale(); // 오류콘솔: 과일사세요 세일함미다!!!
food.raise(); // raise 프로토토메소드실행
console.log(food); // Food {weight: 5, price: 2500, type: '과일'}

// 부모 class
// Food클래스 구조를 상속(공유)받음
class Berries extends Food {
  constructor(color, weight) {
    super(weight);
    this.color = color
  }
}

const berries = new Berries('many', 3);
console.log(berries); // Berries {weight: 3, price: 300, type: '과일', color: 'many'}
berries.sale(); // 상속받은 Food클래스의 sale프로토메소드실행 오류콘솔: 과일사세요 세일함미다!!!

// 자식1 class
// Food, Berries 클래스를 상속(공유)받음
class Strawberry extends Berries {
  constructor(name, color, weight) { // 현재정의할클래스에서사용할매개변수들, 상속하는클래스에서사용할매개변수들
    super(color, weight); // 상속하는클래스에서사용할매개변수들
    this.name = name
  }
  // 오버라이딩: 상속(확장)받은 클래스에있는 있는 기존메소드의 로직을 새로짜서 덮어씀
  sale() {
    if (this.price <= 5000) {
      console.error(`${this.name}가 ${this.price}원!!! 세일함미다!!!`);
      return
    }
    this.price -= this.weight
  }
}

const strawberry = new Strawberry('딸기', 'red', 5);
console.log(strawberry); // Strawberry {weight: 5, price: 500, type: '과일', color: 'red', name: '딸기'}
strawberry.sale(); // 오버라이딩한 sale프로토메소드실행 오류콘솔: 딸기가 500원!!! 세일함미다!!!
strawberry.raise(); // 조부모 Food메소드의 상속받은 raise프로토메소드실행
strawberry.sale(); // 오버라이딩한 slae프로토메소드실행 오류콘솔: 딸기가 2500원!!! 세일함미다!!!

// 자식2 class
class Peach extends Food {
  constructor(season, name, color, weight) {
    super(weight);
    this.season = season
    this.name = name
    this.color = color
  }
}

const peach = new Peach('Summer', 'Peach', 'Pink', 7);
console.log(peach); // Peach {weight: 7, price: 700, type: '과일', season: 'Summer', name: 'Peach', color: 'Pink}

- instanceof

클래스끼리 연관(상속)되어있는 불린값으로 확인
조부모 클레스부터 부모클래스를 커쳐 자손클래스까지 클래스가 상속되어서
자손클래스생성된 인스턴스는 조부모, 부모, 본인 모두 true

인스턴스명 instanceof 클래스명 // true or false

- constructor

클래스는 constructor()함수를 통해 만드는데 인스턴스의 클래스가 검사할 클래스와 일치하는지 불린값으로 확인함
어느 클래스에서 생성된건지 정확한 위치 확인가능

인스턴스명.constructor === 클래스명 //true or false





🎮 패스트캠퍼스
프론트엔드 웹 개발의 모든 것 초격차패키지 Online.

'Javascript' 카테고리의 다른 글

8. [JavaScript] 표준 내장 객체 - Number  (0) 2023.07.31
7. [JavaScript] 표준 내장 객체 - String  (0) 2023.07.27
5. [JavaScript] 함수  (0) 2023.07.25
4. [JavaScript] 연산자와 구문  (0) 2023.07.22
3. [JavaScript] 데이터 타입  (0) 2023.07.22