[데브코스/TIL] DAY18 - JavaScript(7) 클래스

Minha Ahn·2024년 10월 31일
2

데브코스

목록 보기
15/22
post-thumbnail

🗣️ 자바스크립트의 객체지향 언어

2가지 종류의 객체지향 언어

  • 클래스 기반의 객체지향 언어 : 보통의 언어들이 여기에 속한다.
  • 프로토타입 기반의 객체지향 언어 : 자바스크립트가 여기에 속한다.

프로토타입 기반 객체지향 특징

  • 프로토타입 체인
    • 모든 객체가 [[Prototype]]이라는 숨겨진 링크를 가짐
    • [[Prototype]]은 객체가 상속하는 부모 객체를 가르킴 => 객체 간에 메서드와 속성 공유
  • 프로토타입 객체
    • 모든 함수는 prototype이라는 속성 가짐
    • 이 속성은 생성된 객체의 부모 역할을 함
    • 생성자 함수 Person이 있을 때 Person.prototypePerson으로 만들어진 모든 인스턴스의 부모가 된다.
  • 상속
  • 동적 상속 및 메서드 확장
    • 프로그램 실행 중 언제든지 프로토타입에 메서드나 속성을 추가할 수 잇음
    • 프로토타입 체인 전체에 영향을 주고 할 때 유용



🏫 클래스

🔎 클래스란?

프로토타입을 쉽게 사용하기 위한 Sugar Syntax

  • Sugar Syntax : 기존에 존재하던 문법을 쉽게 사용할 수 있게 됨

1. 정의

class Person {
  constructor(name, age) { // 생성자 함수는 필수 아님
    this.name = name;
    this.age = age;
  }
  getInfo() {
    console.log(`${this.name} ${this.age}`);
  }
}

const person = new Person("영희", 30);
console.log(person);

궁금했던 점

클래스로 인스턴스를 생성할 때 생성자 함수거 아님에도 클래스명.prototype이 있다.
왜 있지...?
자바스크립트 엔진이 자동으로 constructor라는 생성자 함수를 정의하기 때문에
클래스로 정의하면 자바스크립트는 내부적으로 함수로 취급하고 이에 따라 프로토타입 속성을 갖게 된다.


2. 상속

extends 키워드

  • 클래스를 상속 받으면 반드시 constructor에 super()를 호출해야 한다.
    • 단, 자식 클래스 내에서 constructor를 명시적으로 작성할 때 호출하면 된다.
    • constructor를 작성하지 않으면 자바스크립트가 알아서 해준다.
  • 클래스를 상속함으로써 자식 클래스는 부모 클래스에 있는 멤버 함수나 멤버 변수를 사용할 수 있다.
  • 이런 상속으로 프로토타입이 체인으로 다 연결되어 있는 것
class Rectangle extends Shape {
  constructor() {
    super();
  }
  getArea() { ... }
}

3. 정적 필드와 정적 메서드

정적 메서드

  • 클래스에 속한 메서드
  • 인스턴스가 아닌 클래스 자체에서 직접 호출
  • 클래스 내부 멤버 변수의 영향을 받지 않으면 정적 메서드로 만들어주는 것도 방법

정적 필드 (정적 변수)

  • 클래스 자체에 할당된 변수
  • 인스턴스가 아닌 클래스 자체에서 접근
  • 변경은 상황에 따라 다른 듯 하다.
class MathUtils {
  static PI = 3.14;
  static add(n1, n2) {
    return n1 + n2;
  };
  static sub(n1, n2) {
    return n1 - n2;
  };
};

const math = new MathUtils();
const sum = math.add(10, 5); // 에러
const sum = MathUtils.add(10, 5); // 이렇게 호출해야 함

4. 접근 제어자 get, set

  • 인스턴스 객체의 속성 값을 바꾸는 과정을 제어하고 싶은 경우에 사용
  • get: 프로퍼티를 부르는 것처럼 호출
  • set: 프로퍼티에 값을 대입하는 것처럼 호출
class Car {
  constructor(speed) {
    this._speed = speed;
  }
  
  set speed(value) {
    this._speed = value < 0 ? 0 : value;
  }
  
  get speed() {
    return this._speed
  }
}

const car = new Car(200);
car.speed = -100; // 0으로 설정
console.log(car.speed);

큰 차이가 없기는 한데 이렇게도 쓰인다.

class Car {
  constructor(speed) {
    this.speed = speed; // 이러면 set speed가 호출된다.
  }

  set speed(value) {
    this._speed = value < 0 ? 0 : value;
  }

  get speed() {
    return this._speed;
  }
}

const car = new Car(200);
car.speed = -100; // 0으로 설정
console.log(car.speed);

주의점은 필드명과 메서드명이 동일하면 안된다는 것! 무한루프 돌 수 있음


5. 프라이빗 필드

  • 멤버 변수명을 #으로 시작하면 외부에서 접근이 불가능함
  • 프로토타입에서도 접근이 불가능함
class Car {
  #speed = 0;

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

  set speed(value) {
    this.#speed = value < 0 ? 0 : value;
  }

  get speed() {
    return this.#speed;
  }
}

const car = new Car(100);
console.log(car.#speed); // 에러

6. 오버라이딩

  • 부모가 가지고 있는 걸 자식이 덮어씌우는 것
class Animal {
  sound() {
    console.log("sound!");
  }
}

class Dog extends Animal {
  run() {
    console.log("run!");
  }

  sound() {
    super.sound(); // 이렇게도 가능
    console.log("Hey");
  }
}
const dog = new Dog();
dog.run();
dog.sound();



🪄 번외

1. instanceof

  • 왼쪽에 있는 식별자가 오른족에 있는 식별자의 인스턴스인지 확인
function Person() {}
const person = new Person();

console.log(person instanceof Person); // true
console.dir(Person.prototype instanceof Object); // true
console.dir(person.prototype instanceof Object); // false

2. 일급 객체

🔎 일급 객체란?

다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체

다른 객체들에 일반적으로 적용 가능한 연산?
솔직히 정의를 보고 무슨 뜻인지 한 번에 이해되지 않았다.

이 말을 쉽게 풀어보겠다.
자바스크립트에는 다양한 객체들이 있다. A 객체도 있고 B 객체도 있고 ~
그리고 각 객체마다 적용 가능한 연산들이 있다.

일급 객체는 각 객체마다 적용 가능한 연산들을 받아들일 수 있는 객체,
그리고 이러한 연산이 다른 객체와 동일하게 사용될 수 있는 객체를 의미한다.

일급 객체 예시

  • 함수, 배열, 객체, ...
  • 문자열, 숫자, ...

일급 객체가 되기 위한 조건

  1. 변수에 할당이 가능해야 한다.
const sum = function() {};
  1. 함수의 인자로 전달할 수 있어야 한다.
function greet(callback) {
  callback();
}
greet(() => {
  console.log("hello");
});
  1. 함수의 반환 값으로 사용할 수 있어야 한다.
function outer() {
  return function() {
    console.log("inner");
  };
}
const fn = outer();
fn();
  1. 동적으로 생성이 가능해야 한다.
const dynamicFunc = new Function("name", "return '안녕하세요, ' + name");
console.log(dynamicFunc("기수"));





📌 출처

수코딩(https://www.sucoding.kr)

profile
프론트엔드를 공부하고 있는 학생입니다🐌

0개의 댓글