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
https://ko.javascript.info/static-properties-methods
https://ko.javascript.info/class
https://github.com/junh0328/prepare_frontend_interview/blob/main/js.md#%ED%81%B4%EB%9E%98%EC%8A%A4
'프론트엔드 개발 > JavaScript' 카테고리의 다른 글
자바스크립트) 타이머 - 디바운스, 쓰로틀링 (0) | 2023.07.12 |
---|---|
자바스크립트) 이벤트 (0) | 2023.07.12 |
자바스크립트) strict 모드 (0) | 2023.06.20 |
자바스크립트) 객체지향 프로그래밍 (0) | 2023.06.19 |
자바스크립트) 프로토타입 (0) | 2023.06.19 |