Chapter 12: Classes

๐Ÿ’ก ๋„์„œ ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•ต์‹ฌ ๊ฐ€์ด๋“œ๋ฅผ ์ฝ๊ณ  ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

12.0 ํด๋ž˜์Šค


MDN์—์„œ๋Š” ํด๋ž˜์Šค๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค๋ช…

ํด๋ž˜์Šค๋Š” ์ผ์ฐจ์ ์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ์กด ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ์ƒ์†์— ๋Œ€ํ•œ ๋ฌธ๋ฒ•์  ์„คํƒ•์ด๋‹ค. ํด๋ž˜์Šค ๋ฌธ๋ฒ•์ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ƒˆ๋กœ์šด ๊ฐ์ฒด ์ง€ํ–ฅ ์ƒ์† ๋ชจ๋ธ์„ ๋„์ž…ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

ํด๋ž˜์Šค๋Š” ์ด๋ฏธ ๊ตฌ์ถ•๋˜์–ด ์žˆ๋˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ถ”๊ฐ€๋œ ๋ฌธ๋ฒ•์ƒ์œผ๋กœ ๋‹ฌ๋‹ฌํ•œ, ์ฆ‰ ํŽธ๋ฆฌํ•จ์„ ์ œ๊ณตํ•˜๋Š” ๋ฌธ๋ฒ•

ํด๋ž˜์Šค์™€ ์˜ค๋ธŒ์ ํŠธ (Class vs. object)

class

class๋ž€ ์กฐ๊ธˆ ๋” ์—ฐ๊ด€์žˆ๋Š” ๊ฒƒ๋“ค์„ ๋ฌถ์–ด ๋†“์€ fields์™€ methods์˜ ์ง‘ํ•ฉ

  • template
  • declare once
  • no data in (data๊ฐ€ ๋“ค์–ด๊ฐˆ fields๋งŒ ๋“ค์–ด์žˆ์Œ)

object

object๋Š” class์— ์ง์ ‘ data๋ฅผ ๋„ฃ์–ด ๋งŒ๋“  instance

  • instance of a class
  • created many times
  • data in

12.1 ํด๋ž˜์Šค ์ƒ์„ฑ


์ƒ์„ฑ ๋ฐฉ๋ฒ•

// ํด๋ž˜์Šค ์„ ์–ธ
class Person {
}

// ํด๋ž˜์Šค ํ‘œํ˜„์‹
const person = class Person {
}

ํด๋ž˜์Šค ์„ ์–ธ ๋ฐ ํ‘œํ˜„์‹์€ ํ˜ธ์ด์ŠคํŒ…์ด ๋ถˆ๊ฐ€๋Šฅํ•จ

ํด๋ž˜์Šค ์„ ์–ธํ•˜๊ธฐ

class Person {
    //constructor
    constructor(name, age) {
        // fields
        this.name = name;
        this.age = age;
    } // ๊ฐ์ฒด์™€ ๋‹ฌ๋ฆฌ ๋ฉ”์„œ๋“œ ์‚ฌ์ด์— ์‰ผํ‘œ ์—†์Œ

    // methods
    speak() {
        console.log(`${this.name}: hello! I'm ${this.name} and ${this.age} years old.`)
    }
}

const newstar = new Person('newstar', 20);

console.log(newstar.age);
newstar.speak();
  • ์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ(constructor)๋Š” ๋‹จ ํ•˜๋‚˜๋งŒ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ

12.2 ์ •์  ๋ฉ”์„œ๋“œ


์•„๋ž˜์™€ ๊ฐ™์ด ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค ์ž์ฒด์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์ž‡๋Š” ์ •์  ๋ฉ”์„œ๋“œ ์ •์˜ ๊ฐ€๋Šฅ

class Person {
  constructor(name,age){
    this.name = name;
    this.age = age;
  }
  static info(){
    console.log("I am a Person class, nice to meet you");
  }
}
const alberto = new Person("Alberto",26);

alberto.info();
// TypeError: alberto.info is not a function

Person.info();
// I am a Person class, nice to meet you

12.3 set์™€ get


Setter and getters

์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ์ž…๋ ฅ ๊ฐ’์„ ๋„ฃ์„ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ๋ฐฉ์–ด์ ์ธ ์ž์„ธ๋กœ ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ๋ฐฉ๋ฒ•

get์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๋กœ ๊ฐ’์„ returnํ•˜๊ณ  set์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๋กœ ๊ฐ’์„ ์„ค์ •

์ปคํ”ผ ์žํŒ๊ธฐ ์˜ˆ์‹œ

  • ์ปคํ”ผ ์žํŒ๊ธฐ - class
  • ์ปคํ”ผ์˜ ์ข…๋ฅ˜ - integer (int a cup of coffee)
  • ๋™์ „ ๋„ฃ๊ธฐ, ์ปคํ”ผ ๋งŒ๋“ค๊ธฐ - methods (put coin, make coffee)

→ ์œ„ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ์ปคํ”ผ์˜ ์ข…๋ฅ˜ ๊ฐ’์— -1์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š”๊ฐ€? ๊ทธ๋Ÿด ์ˆ˜ ์—†๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— getter์™€ setter๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ!

class Person {
  constructor(name,surname) {
    this.name = name;
    this.surname = surname;
    this.nickname = "";
  }
  set nicknames(value){
    this.nickname = value;
    console.log(this.nickname);
  }
  get nicknames(){
     console.log(`Your nickname is ${this.nickname}`);
  }
}

const alberto = new Person("Alberto","Montalesi");

// first we call the setter
alberto.nicknames = "Albi";
// "Albi"

// then we call the getter
alberto.nicknames;
// "Your nickname is Albi"
  • ๋˜ ๋‹ค๋ฅธ ์˜ˆ์‹œ์œ„ ์ฝ”๋“œ get๊ณผ set ๊ตฌ๋ฌธ ์•ˆ์—์„œ this.age๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋˜๋Š” ์ด์œ 
  • Chapter%2012%20Classes%205753ccb43d5b4052b50eab15d35acd88/Untitled.png
  • class User { constructor(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } get age() { return this._age; // this.age๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด call stack ์ดˆ๊ณผ ์˜ค๋ฅ˜๊ฐ€ ๋œธ. ๊ด€์šฉ์ ์œผ๋กœ _(์–ธ๋”๋ฐ”) ์‚ฌ์šฉ. } set age(value) { //if (value < 0) { // throw Error('age can not be negative.'); //} this._age = value < 0 ? 0 : value; } } const user1 = new User('Steve', 'Job', -1); console.log(user1.age); // 0

12.4 ํด๋ž˜์Šค ์ƒ์†ํ•˜๊ธฐ


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;
    }
}

class Rectangle extends Shape {}

class Triangle extends Shape {
    constructor(width, height, color, position) {
        super(width, height, color)
        this.position = position;
    }
  draw() { // ๋ถ€๋ชจ class์˜ ๋ฉ”์„œ๋“œ๋ฅผ Overwritingํ•˜์—ฌ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Œ
        super.draw(); // ์ƒ์†๋ฐ›์€ ๋ถ€๋ชจ class์˜ draw ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ
    console.log('Ta-da! triangle :)');
  }
    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', 'inside');
triangle.draw();
console.log(triangle.getArea());

12.5 ๋ฐฐ์—ด ํ™•์žฅํ•˜๊ธฐ


๋ฐฐ์—ด(Array)์„ ์ƒ์†๋ฐ›์•„ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Œ

class Classroom extends Array {
  // rest๋ฅผ ์ด์šฉํ•ด ๊ฐ€๋ณ€ ์ธ์ˆ˜๋กœ ์ž…๋ ฅ๋ฐ›์€ ํ•™์ƒ๋“ค์˜ ์ •๋ณด๋ฅผ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ students์— ํ• ๋‹น
  constructor(name, ...students){
    // spread๋ฅผ ์ด์šฉํ•ด ๋ฐฐ์—ด์„ ๋‹ค์‹œ ํ’€์–ด ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ (spread ์‚ฌ์šฉ ์•ˆ ํ•˜๋ฉด ๋ฐฐ์—ด์ด ์ƒ์„ฑ๋จ)
    super(...students);
    this.name = name;
  }
    // ํ•™์ƒ ์ถ”๊ฐ€๋ฅผ ์œ„ํ•œ ๋ฉ”์„œ๋“œ
  add(student){
    this.push(student);
  }
}
const myClass = new Classroom('1A',
  {name: "Tim", mark: 6},
  {name: "Tom", mark: 3},
  {name: "Jim", mark: 8},
  {name: "Jon", mark: 10},
);

// ์ƒˆ๋กœ์šด ํ•™์ƒ ์ถ”๊ฐ€
myClass.add({name: "Timmy", mark:7});
myClass[4];
// Object { name: "Timmy", mark: 7 }

// for of ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜๋ณต ๊ฐ€๋Šฅ
for(const student of myClass) {
  console.log(student);
  }
// Object { name: "Tim", grade: 6 }
// Object { name: "Tom", grade: 3 }
// Object { name: "Jim", grade: 8 }
// Object { name: "Jon", grade: 10 }
// Object { name: "Timmy", grade: 7 }

๐Ÿ“Ž ์ฐธ๊ณ