클래스

현성·2023년 11월 30일
1

😃 prototype

// const fruits = ["Apple", "Banana", "Cherry"];
const fruits = new Array("Apple", "Banana", "Cherry");

console.log(fruits); // ["Apple", "Banana", "Cherry"]
console.log(fruits.length); // 3
console.log(fruits.includes("Banana")); // true
console.log(fruits.includes("orange")); // false

Array.prototype.heropy = function () {
  console.log(this);
};

fruits.heropy(); // ["Apple", "Banana", "Cherry"]

const arr = [];
arr.heropy(); // []

이 때 fruits라는 데이터는 결과적으로 생성자 함수에서 반환된 하나의 instance라고 볼 수 있습니다.

인스턴스(instance)란 ??

  • 객체 지향 프로그래밍에서 인스턴스는 해당 클래스의 구조로 컴퓨터 저장공간에서 할당된 실체를 의미합니다.

const HS = {
  firstName: "AA",
  lastName: "HS",
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  },
};

const neo = {
  firstName: "Neo",
  lastName: "Anderson",
};

console.log(HS.getFullName()); // AA HS
console.log(HS.getFullName.call(neo)); // Neo Anderson

위와 같은 방식으로 코드를 작성하면 getFullName 메서드를 사용할 때마다 call 메서드를 사용해줘야하는 단점이 있습니다. 다음의 코드는 이러한 단점을 보완하기 위한 방법입니다.


function User(first, last) {   // 함수명 대문자 Pascal case로 작성
  this.firstName = first;
  this.lastName = last;
}
User.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`;
};

const hs = new User("AA", "hs"); // new는 생성자 함수
const neo = new User("Neo", "Anderson");

console.log(hs);
console.log(neo);

console.log(hs.getFullName()); // AA hs
console.log(neo.getFullName()); // Neo Anderson

✏️ ES6 Classes

class User {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const hs = new User("aa", "hs");
const neo = new User("Neo", "Anderson");

console.log(hs.getFullName()); // AA hs
console.log(neo.getFullName()); // Neo Anderson

Getter, Setter

getter는 값을 반환할 때, setter는 값을 할당할 떄 사용됩니다.
gettersetter를 사용하면 메소드를 마치 속성(property)처럼 사용할 수 있게 됩니다.

class User {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
    this.fullName = `${first} ${last}`;
  }
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const hs = new User("hs", "lim");

console.log(hs.fullName); // hs lim
console.log(hs.getFullName()); // hs lim

hs.firstName = "Neo";

console.log(hs.fullName); // hs lim
console.log(hs.getFullName()); // Neo lim

이 때 console.log(hs)를 작성하면 lastName은 Neo로 바뀌지만 fullName은 hs lim으로 그대로 출력됩니다.
이 것을 해결하기 위해 getFullName메소드를 정의하고 console.log(hs.getFullName())으로 출력하면 firstName이 Neo로 바뀌어 출력되지만 매 번 getFullName을 호출해줘야한다는 단점이 있습니다. 그래서 우리가 사용할 수 있는 것이 바로 getter입니다.

  • getter 사용
class User {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const hs = new User("hs", "lim");

console.log(hs.fullName);

hs.firstName = "Neo";

console.log(hs.fullName);

이제 fullName이라는 메소드를 마치 속성처럼 사용할 수 있습니다.

  • setter 사용
class User {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
  set fullName(value) {
    console.log(value); // Neo Anderson
  }
}

const hs = new User("hs", "lim");

console.log(hs.fullName);

hs.firstName = "Neo";

console.log(hs.fullName);

hs.fullName = "Neo Anderson";
class User {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
  set fullName(value) {
    console.log(value);
    [this.firstName, this.lastName] = value.split(" ");
  }
}

const hs = new User("hs", "lim");

console.log(hs.fullName);

hs.firstName = "Neo";

console.log(hs.fullName);

hs.fullName = "Neo Anderson";
console.log(hs);

정적 메소드 (Static method)

class User {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
  static isUser(user) {
    if (user.firstName && user.lastName) {
      return true;
    } else {
      return false;
    }
  }
}

// 생성자 함수로 생성된 hs, neo는 instance입니다.
const hs = new User("hs", "lim");
const neo = new User("Neo", "Anderson");
const lewis = {
  name: "Lewis Yang",
  age: 20,
};

console.log(hs.getFullName());
console.log(neo.getFullName());
console.log(User.isUser(hs)); // true
console.log(User.isUser(neo)); // true
console.log(User.isUser(lewis)); // false
console.log(hs.isUser()); // 정적 메소드는 인스턴스에는 사용할 수 없기 때문에 에러가 발생합니다.

상속 (Inheritance)

// 운송수단
class Vehicle {
  constructor(acceleration = 1) {
    this.speed = 0;
    this.acceleration = acceleration;
  }
  accelerate() {
    this.speed += this.acceleration;
  }
  decelaerate() {
    if (this.speed <= 0) {
      console.log("정지!");
      return;
    }
    this.speed -= this.acceleration;
  }
}

// 자전거
class Bicycle extends Vehicle {
  constructor(price = 100, acceleration) {
    super(acceleration); // Vehicle의 constructor를 가져오는 역할을 합니다.
    this.price = price;
    this.wheel = 2;
  }
}

const bicycle = new Bicycle(300);
bicycle.accelerate();
bicycle.accelerate();
console.log(bicycle);

// 인스턴스 instanceof 클래스 => 해당 클래스의 인스턴스인지 확인할 때 사용합니다.
console.log(bicycle instanceof Bicycle); // true
console.log(bicycle instanceof Vehicle); // true

// 자동차
class Car extends Bicycle {
  constructor(license, price, acceleration) {
    super(price, acceleration);
    this.license = license;
    this.wheel = 4;
  }
  accelerate() {
    // 같은 이름으로 accelerate 메소드를 재 정의합니다. : 오버라이딩 (Overriding)
    if (!this.license) {
      console.error("무면허!");
      return;
    }
    this.speed += this.acceleration;
    console.log("가속!", this.speed);
  }
}

const carA = new Car(true, 7000, 10);
const carB = new Car(false, 4000, 6);

carA.accelerate();
carA.accelerate();
carB.accelerate();
console.log(carA);
console.log(carB);

console.log(carA instanceof Vehicle); // true
console.log(carB instanceof Car); // true

// 보트
class Boat extends Vehicle {
  constructor(price, acceleration) {
    super(acceleration);
    this.price = price;
    this.motor = 1;
  }
}

const boat = new Boat(10000, 5);
console.log(boat);
console.log(boat instanceof Boat); // true
console.log(boat instanceof Bicycle); // false

instanceof와 constructor

class A {
  constructor() {}
}

class B extends A {
  constructor() {
    super();
  }
}

class C extends B {
  constructor() {
    super();
  }
}

const a = new A();
const b = new B();
const c = new C();

console.log(a instanceof A); // true
console.log(a instanceof B); // false
console.log(a instanceof C); // false

console.log(b instanceof A); // true
console.log(b instanceof B); // true
console.log(b instanceof C); // false

console.log(c instanceof A); // true
console.log(c instanceof B); // true
console.log(c instanceof C); // true

console.log(a.constructor === A); // true
console.log(a.constructor === B); // false
console.log(a.constructor === C); // false

console.log(b.constructor === A); // false
console.log(b.constructor === B); // true
console.log(b.constructor === C); // false

console.log(c.constructor === A); // false
console.log(c.constructor === B); // false
console.log(c.constructor === C); // true
profile
👈🏻 매일 꾸준히 성장하는 개발자 !

0개의 댓글