클래스 (class) 란 ❓
MDN에서 클래스를 다음과 같이 설명한다.
클래스는 일차적으로 자사크르비트의 기존 프로토타입 기반 상속에 대한 문법적 설탕(syntax sugar)이다.
클래스 문법이 자바스크립트에 새로운 객체 지향 상속 모델을 도입하는 것은 아니다. 라고
문법적 설탕(Syntax Sugar)이란 ❓Syntax Sugar는 한국어로 문법 설탕이라고 번역된다.JS뿐만 아니라 프로그래밍 언어 전반적으로 적용되는 개념이며, 달달한 이름에 걸맞게 읽는 사람 또는 작성하는 사람이 편하게 디자인 된 문법이라는 뜻을 갖고 있다. |
본격적으로 클래스를 살펴보기 전에 프로토타입 상속 예시를 먼저 보자.
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function(){
console.log("Hello, my name is " + this.name)
}
const KimJiWoo = new Person("JiWoo", 27)
const OhJiHyun = new Person("JiHyun", 25)
KimJiWoo.greet();
// Hello, my name is JiWoo
OhJiHyun.greet();
// Helle, my name is JiHyun
Person의 프로토타입에 새 메소드를 추가해서 Person 객체의 인스턴스들이 접근할 수 있도록 만들었다.
포로토타입 상속을 위한 코드가 어떻게 작성되는지 살펴봤으니 이제 클래스를 본격적으로 살펴보자.
✔ 클래스 생성
클래스를 만드는 방법에는 두 가지가 있다.
클래스 선언과 클래스 표현식이다.
class Person {
// 클래스 선언
}
const person = class Person {
// 클래스 표현식
}
기억하자.
"클래스 선언 및 클래스 표현식은 호이스팅되지 않는다"
클래스에 접근하기 전에 클래스를 선언하지 않으면 ReferenceError가 발생한다.
그럼 이제 첫 번째 클래스를 만들어보자.
생성자 메소드를 추가한 것을 제외하면 프로토타입 방식과 큰 차이가 없다
(생성자를 하나만 추가해야 함에 주의하자. 클래스에 생성자 메소드가 두 개 이상 포함된 경우 Syntax에러가 발생한다.)
class Person{
constructor(name, age) {
this.name = name;
this.age = age;
}
greet(){
console.log(`HI, my name is ${this.name} and I'm ${this.age} years old`)
} // 메소드와 메소드 사이에는 쉼표가 없음
farewell() {
console.log("goodbye friend")
}
}
const JiWoo = new Person("JiWoo", 27)
JiWoo.greet();
//HI, my name is JiWoo and I'm 27 years old
JiWoo.farewell();
//goodbye friend
보다시피 모든 것이 이전과 동일하게 작동한다.
앞에서 언급했듯이 클래스는 프로토타입 방식을 대신하는 문법적 설탕일 뿐이다.
✔ 정적 메소드
앞의 예시에서 추가한 greet()와 farewell() 메소드는 Person 클래스의 모든 인스턴스에서 접근할 수 있지만, Array.of()처럼 클래스의 인스턴스가 아닌 클래스 자체에서 접근할 수 있는 정적 메소드는 다음과 같이 정의할 수 있다.
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 Jiwoo = new Person("JiWoo", 27)
Jiwoo.info();
// Error : Jiwoo.info is not a function
Person.info();
// I am a Person class, nice to meet you
✔ set와 get
세터(setter)와 게터(getter) 메소드를 사용하여 클래스 내에 값을 설정하거나 가져올 수 있다.
👏 Getter
getter는 어떤 프로퍼티(property)에 접근할 때마다 그 값을 계산하도록 해야 하거나 내부 변수의 상태를 명시적인 함수 호출 없이 보여주고 싶을 때 Javascript의 getter를 이용할 수 있다.
👏 Setter
자바스크립트에서 setter는 특정한 속성에 값이 변경될 때마다 함수를 실행하는데 사용될 수 있다.
Setter는 유사 property 타입을 생성하는 getter와 함께 사용된다.
getter와 setter는 class를 사용하는 사용자가 잘못 사용해도 오류를 방어할 수 있도록 할 수 있다.
바인딩(binding)이란 프로그램에 사용된 구성 요소의 실제 값 또는 프로퍼티를 결정짓는 행위를 의미한다. 예를 들어 함수를 호출하는 부분에서 실제 함수가 위치한 메모리를 연결하는 것도 바로 바인딩이다.
프로퍼티(property)는 일부 객체 지향 프로그래밍 언어에서 필드(데이터 멤버)와 메소드 간 기능의 중간인 클래스 멤버의 특수한 유형이다. 프로퍼티의 읽기와 쓰기는 일반적으로 게터(getter)와 세터(setter) 메소드 호출로 변환된다.
간단히 정리하자면, 세터(setter)은 property에 값을 쓸 때 호출되고, 게터(getter)는 property를 읽을 때 동작한다
class Person {
constructor(name, surname) {
this.nem = name;
this.surname = surname;
this.nickname = "";
}
set nicknames(value) {
this.nickname = value;
console.log("nickname : " + this.nickname)
}
get nicknames() {
console.log(`Your nickname is ${this.nickname}`)
}
}
const JiWoo = new Person("JiWoo", "KJW")
// 세터를 호출
JiWoo.nicknames = "setterNickname"
// nickname : setterNickname
// 게터를 호출
JiWoo.nicknames;
// Your nickname is setterNickname
✔ 클래스 상속하기
상속은 객체지향에서 아주 중요한 개념으로 클래스 상속을 사용하면 클래스를 다른 클래스로 확장할 수 있다.
즉, 기존에 존재하던 기능을 토댈로 새로운 기능을 만들 수 있다.
기존 클래스로부터 상속된 새로운 클래스를 만들려면 extends 키워드를 사용한다.
바로 예시를 살펴보도록 하자
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet(){
console.log(`HI, my name is ${this.name} and I'm ${this.age} years old`)
}
}
class Adult extends Person {
constructor(name, age, work){
this.name = name;
this.age = age;
this.work = work;
}
}
Person을 상속하는 Adult 클래스를 만들었지만 이 코드를 실행하려고 하면 오류가 발생한다.
ReferenceError: must call super constuctor before using :this: in Adult class constuctor
오류메시지는 새로운 클래스에서 this를 사용하기전에 super()를 호출하라는 내용이다.
즉 Adult를 만들기에 앞서 Pweson을 만들어야 한다는 것이다.
생성자 내부에서 super()를 호출하면 Person이 만들어진다.
class Adult extends Person {
constructor(name, age, work){
super(name, age)
this.work = work;
}
}
여기서 왜 super(name, age) 형태로 호출했을까?
Adult 클래스는 Person으로부터 이름과 나이를 상속받기 때문에 Person을 다시 선언하고 초기화할 필요가 없다.
super() 생성자가 하는 일이 바로 이것이다.
✔ 배열 확장하기
배열과 비슷하게 생겼지만 첫 번째 값은 교실 이름이고 나머지는 학생 이름과 학생 점수를 나타내는 Classroom이라는 새로운 클래스를 만들어보자. 이 클래스는 다음과 같이 사용할 수 있어야 한다.
const myClass = new Classrom('1A',
{name: "Tim", mark: 6},
{name: "Tom", mark: 3},
{name: "Jim", mark: 8},
{name: "Jon", mark: 10},
);
이러한 요구 사항을 만족시키는 새로운 클래스는 다음과 같이 배열을 상속받아서 만들 수 있다.
출처 : 모던 자바스크립트 핵심 가이드 서적
'자바스크립트 - Vanilla JS' 카테고리의 다른 글
[자바스크립트 / Vanilla JS] parseInt()와 Number()의 차이점 (0) | 2022.09.22 |
---|---|
[자바스크립트 / Vanilla JS] 스프레드 연산자 (Spread Operator) (1) | 2022.09.21 |
[자바스크립트 / Vanilla JS] Array(배열) - filter, reduce, map (1) | 2022.09.14 |
[자바스크립트 / Vanilla JS] 디스트럭처링이란 ? (객체 디스트럭처링, 배열 디스트럭처링) (1) | 2022.09.13 |
[자바스크립트 / Vanilla JS] 함수 기본값 인수 (0) | 2022.09.13 |