프론트엔드 개발/JavaScript

자바스크립트) class 끝장 정리

Ella Seon 2023. 6. 21. 16:08

0. class

- ES6 의 클래스가 도입되기 이전에는 생성자 함수로 프로토타입 기반의 인스턴스를 생성했다.

- ES6 클래스 문법은 좀더 Java 스럽게 객체지향적으로 표현하기 위해 추가된 새로운 문법이다. 

- 결국엔 object 를 여러개 만들기 위해서 class 를 쓰는 것이다. 

1. class 만드는 방법

🔸class 를 선언하는 방법

class 에는 constructor 라고 하는 키워드를 넣어야한다.

 

1)클래스 선언문

class MySelf {
  constructor(age, height) {
    this.age = age;
    this.height = height;
  }
}

2) 변수에 클래스를 선언(기명 클래스 표현식)

const MySelf = class MySelf {
  constructor(age, height) {
    this.age = age;
    this.height = height;
  }
}

 

3) 변수에 클래스 이름 없이 선언(익명 클래스 표현식)

const MySelf = class {
  constructor(age, height) {
    this.age = age;
    this.height = height;
  }
}

🔸class 몸체에 정의할 수 있는 메서드 (constructor / 프로토타입 메서드 / 정적 메서드)

1️⃣ constructor

- 인스턴스를 생성하고 초기화 하기 위한 특수한 메서드 (constructor이름 변경 불가)
- 프로토타입의 constructor 프로퍼티와 전혀 관계 없음
- constructor에서 작성한 this는 인스턴스를 가리킴

2️⃣ 프로토타입 메서드
- 명시적으로 프로토타입에 할당하지 않고, (ex : Parent.prototype.name = ‘kim) 축약형 메서드를 정의하면 자동으로 프로토타입 메서드가 됨

-인스턴스는 상속받아 프로토타입 메서드를 사용할 수 있음

3️⃣ 정적 메서드
- prototype이 아닌 클래스 함수 자체에도 메서드를 설정할 수 있는 것
- 인스턴스를 통해 호출 할 경우 에러가 난다.
호출은 '클래스명.메소드명' 을 사용한다.


- static method 만 있는 경우엔 constructor 생략이 가능하다. 
인스턴스를 생성하지 않아도 호출할 수 있는 메서드



- this : 생성자 함수와 마찬가지로 this는 어디서 호출됐는지에 따라서 this가 달라지기 때문에 constructor의 this는 인스턴스를, 정적 메서드의 this는 클래스 자체를 가리킴



- 인스턴스와 독립적으로 동작하는 메서드이기 때문에, constructor에 선언된 인스턴스의 변수에 직접 접근할 수 없다. 
즉, this 키워드를 이용해서 인스턴스 변수에 접근할 수 없다. 



+) 그래서 정적 메서드 언제쓰는건데?

인스턴스를 생성하지 않고도 직접 클래스 이름을 통해 호출할 수 있기에 인스턴스 상태에 의존하지 않고, 독립적으로 작동하는 기능을 제공하는 함수를 정의할 때 유용하다.

class StringUtil {
  static reverseString(str) {
    return str.split('').reverse().join('');
  }
}

console.log(StringUtil.reverseString('Hello')); // 출력: "olleH"

 

+) 정적메서드와 프로토타입 메서드의 차이

  프로토타입 메서드 정적 메서드
프로토타입 클래스의 프로토타입에 정의 된 메서드 클래스 자체에 속하는 메서드
호출 방법 인스턴스에서 호출 가능 인스턴스를 생성하지 않고, 클래스 이름을 통해 직접 호출 가능
constructor 내부에서 생성된 인스턴스 접근 접근 O 접근 X

this 키워드를 사용하여 인스턴스 변수에 접근 불가능 

 


🔸class 안에 method를 넣는 방법

1번 : constructor 안에 함수를 넣는 것은 자식이 직접 함수를 갖고 싶게 할 때 

2번 : constructor 밖에 함수를 넣는 것은 부모의 prototype 에만 만들어 놓고 싶을 때. 그러면 모든 자식들이 공통적으로 쓸 수 있는 내장함수 같은 것을 만들 수 있다. 

class 를 사용하고 싶을 때는 아래처럼 사용하면 된다. 


🔸자식.__proto__ 랑 Object.getPrototypeOf(자식) 했을 때 부모의 prototype을 알려준다.

constructor 함수 밖에다가 메서드를 넣었을 때는 모든 자식들이 공통으로 쓰는 함수를 만들 수 있다고 했었다. 

그렇다면

부모.prototype.sayHello = function(){console.log('굿모닝')} 이라고 해도 똑같지 않은가??


🤔constructor 밖에 쓰는 메서드랑, prototype 추가하는거랑 똑같은데 뭐가다른겨??

class라는 키워드 없이도 클래스 역할을 하는 함수를 선언할 수 있기 때문에 클래스는 '편의 문법’에 불과하다고 이야기 한다.  참고로 기능은 동일하나 기존 문법을 쉽게 읽을 수 있게 만든 문법을 편의 문법(syntactic sugar, 문법 설탕)이라고 합니다.

 

아래 예제처럼 생성자 함수로 prototype 선언하는 것과 class 키워드 사용하는 방법의 결과는 같다. 

생성자함수 class

🔸생성자 함수와 클래스는 구체적으로 어떤 차이가 있을까?

 

1) new 연산자

// class 생성
class exampleClass {
  constructor(){}
}

// 생성자 함수 생성
function ExampleFunc(){}


// 호출
exampleClass(); // new 연산자가 없으면 Error
ExampleFunc(); // 에러가 나지 않음 -> 일반함수가 되기 때문

2) 호이스팅

class 는 'let','const'와 같이 TDZ 에 놓인다. 또한, 선언시점에서 초기화 되기 때문에 선언 전에 접근 할수가 없어서 참조오류가 발생한다. (TDZ : 변수 선언과 초기화 되기 전까지의 구간으로 변수를 참조할 수 없는 구간, tdz에서는 선언 되기 전이나 초기화 되기 전인 상태의 변수를 사용하는 것을 허용하지 않음)

 

즉, 호이스팅은 되지만 TDZ 때문에 호이스팅이 안되는 것처럼 보인다. 

var v = new MyClass(); // ReferenceError
class MyClass {}


2. class 상속 및 오버라이딩 super 키워드

🔸extends 를 쓰는 이유

  • 만들어놓은 class랑 유사한 class를 하나 더 만들고 싶을때
  • 이미 만들어 놓은 class를 상속하는것. class 복사하기

🔸JS class 오버라이딩의 종류

오버라이딩 : 부모 메서드를 토대로 일부 기능만 변경하고 싶을 때, 또는 부모의 메서드의 기능을 확장하고 싶을 때 작업한다.

메서드 오버라이딩 super.method( )는 부모 클래스에 정의된 메서드, method를 호출한다.
생성자 오버라이딩 super(...) 는 부모 생성자를 호출하는데, 자식 생성자 내부에서만 사용할 수 있다.

 

부모 클래스가 가진 특성을 그대로 물려받은 Student라는 class를 만들어보자.
extends 키워드가 필요하다. 

물려받고 싶은 인스턴스를 super 키워드를 쓰면 물려받을 수 있다. 

super : 1)상위(부모) 객체의 함수를 호출할 때 사용됨
2) 클래스의 constructor 에서는 super 키워드는 하나만 사용되거나, this 키워드가 사용되기전에 호출되어야한다.  (super 키워드를 사용하지 않으면, reference Error 발생)

3) constructor 바깥 메소드 에서 (ex: avg) super를 쓰면 부모 class의 prototype을 의미. 즉 부모 prototype에 각인된 sum() 메소드를 실행시켜주세요

3. 추상화

- 추상화는 클래스를 만들 때 일반적인 특징과 동작을 정의하고, 이를 기반으로 구체적인 객체를 생성하는 것을 의미함

- 아래 예제처럼 클래스를 추상화하면 클래스의 공통적인 특징과 동작을 재사용할 수 있으며, 객체간의 관계를 명확히 표현할 수 이싸. 추상화는 코드의 가독성과 유지보수성을 향상시키는데 도움을 줄 수 있다. 

class AbstractClass {
  constructor() {
    // 공통적인 속성 초기화
    this.property = value;
  }

  method() {
    // 공통적인 동작 구현
  }
}

class SubClass extends AbstractClass {
  constructor() {
    super();
    // 서브 클래스의 생성자 로직
  }
}

var instance = new SubClass();

참고자료

https://chanyeong.com/blog/post/24

 

모던 자바스크립트 : 정적 프로퍼티와 정적 메서드 :: chanyeong

정적 메서드 prototype이 아닌 클래스 함수 자체에도 메서드를 설정할 수 있다. 이런 메서드를 정적(static) 메서드라고 한다. 즉 정적 메서드는 인스턴스 없이 클래스에서 바로 호출이 가능하고 이

chanyeong.com

https://ko.javascript.info/static-properties-methods

 

정적 메서드와 정적 프로퍼티

 

ko.javascript.info

https://velog.io/@sjoleee_/class%EC%99%80-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98%EC%9D%98-%EC%B0%A8%EC%9D%B4-nfhwxkux

 

class와 생성자 함수의 차이

객체를 찍어내는 공장 class와 factory function 생성자 함수의 차이

velog.io

https://ko.javascript.info/class

 

클래스와 기본 문법

 

ko.javascript.info

https://github.com/junh0328/prepare_frontend_interview/blob/main/js.md#%ED%81%B4%EB%9E%98%EC%8A%A4

 

GitHub - junh0328/prepare_frontend_interview: 📚 프론트엔드 기술 면접을 위한 핸드북 만들기

📚 프론트엔드 기술 면접을 위한 핸드북 만들기. Contribute to junh0328/prepare_frontend_interview development by creating an account on GitHub.

github.com