1. 클래스 기본 문법
* 클래스란
- 클래스는 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀이다.
- 클래스는 전부 혹은 일부를 그 클래스 특성으로부터 상속받는 서브클래스를 가질 수 있으며, 클래스는 각 서브클래스에 대해 수퍼클래스가 된다.
- 동일한 종류의 여러 객체를 생성할 때 new function을 사용할 수도있지만 자바스크립트의 클래스 문법을 사용하면 객체 지향 프로그래밍의 다양한 기능을 사용할 수 있다.
* 기본 문법
- 클래스를 만드는 기본 문법은 다음과 같다.
class MyClass {
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
- 위와 같이 클래스를 만든 후 new MyClass()를 호출하여 객체를 생성할 수 있다.
- 메서드 사이에 쉼표가 없다는 것에 유의하자.
- constructor은 객체의 기본 상태를 설정하는 생성자 메서드로써 new에 의해 자동으로 호출된다.
class User {
constructor(name) {
this.name = name;
}
sayHi() {
console.log("Hello",this.name);
}
}
let user = new User("Harry");
user.sayHi();
// Hello Harry
- 새로운 객체 user가 생성되고 constructor가 자동으로 실행되며 인수가 this.name에 할당되었다.
- 참고로 자바스크립트에서 클래스는 함수의 한 종류로써 typeof User을 콘솔에서 확인해보면 function이 출력된다.
- 그러나 특수 내부프로퍼티로 class를 명시하므로 단순히 User();라고 작성하면 에러가 발생한다.
* getter와 setter
- get과 set을 이용해서 위에서 봤던 user.name을 조작해보자.
class User {
constructor(name) {
// setter를 활성화
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 3) {
console.log("이름을 3자 이상으로 입력하세요.");
return;
}
this._name = value;
}
}
let user = new User("Harry");
console.log(user.name);
// Harry
user = new User("a");
// 이름을 3자 이상으로 입력하세요.
console.log(user.name)
// undefined
- 위와 같은 방식을 사용하면 User.prototype에 getter와 setter가 만들어진다.
2. 클래스 상속
* extends
- 클래스 상속을 사용하면 기존 클래스를 다른 클래스로 확장할 수 있다.
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name} 은/는 속도 ${this.speed}로 달립니다.`);
}
stop() {
this.speed = 0;
alert(`${this.name} 이/가 멈췄습니다.`);
}
}
let animal = new Animal("동물");
- 먼저 동물을 나타내는 Animal 클래스를 만들었다.
- 이제 토끼를 나타내는 클래스 Rabbit을 만들어보자. 토끼는 동물이므로 위 클래스를 확장해서 만들면 동물이 하는 동작도 수행할 수 있게 된다.
class Rabbit extends Animal {
jump() {
alert(`${this.name} 이/가 껑충껑충!`);
}
}
let rabbit = new Rabbit("흰 토끼");
rabbit.run(11); // 흰 토끼 은/는 속도 11로 달립니다.
rabbit.jump(); // 흰 토끼 이/가 껑충껑충!
- 이제 Rabbit으로 만든 객체는 rabbit.run()과 같은 Animail에서 만든 메서드에도 접근 가능하다.
- extends는 프로토타입을 기반으로 작동한다. new Rabbit의 [[Prototype]]은 Rabbit.prototype이 되지만 이 Rabbit.prototype의 [[Prototype]]은 Animal.prototype이 되는 것이다. 따라서 Rabbit.prototype에서 메서드를 찾지 못하면 자동으로 Animal.prototype에서 메서드를 가져온다.
* 메서드 오버라이딩
- 부모 메서드를 이용해서 일부 기능을 변경하고 싶으면 어떻게 해야할까. 부모 메서드의 기능을 확장하는 메서드를 작성해보자. 이럴 때 사용하는 것이 super이다.
- super.method()는 부모 클래스의 method를 호출한다.
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name}가 속도 ${this.speed}로 달립니다.`);
}
stop() {
this.speed = 0;
alert(`${this.name}가 멈췄습니다.`);
}
}
class Rabbit extends Animal {
jump() {
alert(`${this.name}가 껑충껑충!`);
}
run(speed) {
super.run(speed);
this.jump();
}
}
let rabbit = new Rabbit("흰 토끼");
rabbit.run(15);
// 흰 토끼가 속도 15로 달립니다.
// 흰 토끼가 껑충껑충!
rabbit.stop();
// 흰 토끼가 멈췄습니다.
- Rabbit의 run 메서드는 부모의 run을 호출할 수 있게 되었다.
- 참고로 화살표 함수엔 super가 없으니 유의하자.
* 생성자 오버라이딩
- 지금까지 확장을 할 때 constructor을 비워뒀는데, 이 때 기본적으로 생성자는 부모 constructor을 호출한다.
- 커스텀 생성자를 추가해보자.
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
// ...
}
class Rabbit extends Animal {
constructor(name, earLength) {
super(name);
this.earLength = earLength;
}
// ...
}
let rabbit = new Rabbit("흰 토끼", 10);
alert(rabbit.name); // 흰 토끼
alert(rabbit.earLength); // 10
alert(rabbit.speed); // 0
- 상속 클래스 생성자에서는 반드시 super을 호출해 부모 생성자를 실행해야한다. 상속 클래스는 일반 클래스와 달리 빈 객체를 만들고 this에 이 객체를 할당하지 않는다. 상속클래스의 생성자 함수는 빈객체를 만들고 this에 이 객체를 할당하는 일을 부모 클래스의 생성자가 처리해주기를 기대한다. 따라서 this를 사용하기 전에 super()를 꼭 호출해야한다.
참고
모던 자바스크립트 튜토리얼
위키백과
'Language > JavaScript' 카테고리의 다른 글
<자바스크립트> 콜백 (0) | 2021.04.19 |
---|---|
<자바스크립트> try catch & 에러 (0) | 2021.04.16 |
<자바스크립트> 프로토타입 (0) | 2021.04.12 |
<자바스크립트> JSON과 메서드 (0) | 2021.04.07 |
<자바스크립트> 구조 분해 할당 (0) | 2021.03.07 |