자바스크립트에서 클래스 사용 javascript, class
자바스크립트의 클래스와 객체 class, object
- 자바스크립트의 클래스는 다음과 같이 선언한다.
class User {
constructor(name) {
this.name = name;
}
// this._name은 필드
get name(){
return `당신의 이름은 ${this._name} 입니다.`;
}
// this.name 은 함수
get name2(){
return `${this.name}` ;
}
get callName(){
return this._name;
}
set name(value){
if(value.length < 2){
alert('이름이 짧습니다.');
return;
}
this._name = value;
}
age = 15;
static hello(){
return "gday!";
}
}
const user = new User('kim');
console.log(user.name);
console.log(user.name2);
console.log(user.callName);
console.log(user._name);
console.log(user.age);
console.log(user._age);
console.log(User.prototype.age); // 필드에서 바로 주입할 경우 프로토타입의 기능으로 동작하지 않는다.
console.log(User.prototype.name);
console.log(User.hello);
console.log(User.hello());
- 자바 사용자의 입장에서 자바스크립트의 클래스의 작성과 선언은 다음과 같은 특징을 지닌다.
- 필드가 묵시적으로 작성된다.
this.name = "abc";
라고 선언하면, name 필드를 명시하지 않더라도, name이 생성된다. - getter와 setter가
get
과set
으로 사용가능하다. getter보다는 setter의 작성이 특이하다.set name()
메서드를 구현할 경우this.name = nane;
를 할 때, setter 가 동작한다. 자바는 명시적으로setName(name);
을 해야하는 것과 차이를 가진다. 이와 대비하여 getter는 제한 없이 자유롭다.
- 필드가 묵시적으로 작성된다.
- 자바스크립트는 자바와 달리
function User
의 형태로도 객체를 생성할 수 있다. function 객체는 static method를 만들 수 없다. 하지만 클래스는 가능하다.User.hello()
의 형태로 자바와 동일하게 사용 가능하다.
상속 extends
- 자바스크립트는 상속을 지원한다. 다음과 같이 작성한다.
class Animal{
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed){
this.speed = speed;
console.log(`${this.name}의 속도는 ${this.speed}입니다.`);
}
stop(){
this.speed = 0;
console.log(`${this.name}이 멈췄다.`);
}
}
class Rabbit extends Animal {
hide(){
console.log(`${this.name}가 숨었다.`);
}
// override
stop(){
super.stop();
this.hide();
}
}
let rabbit = new Rabbit('토끼');
rabbit.hide();
rabbit.run(5);
rabbit.stop(); // 재정의한 stop()이 동작한다.
- 다만 자바스크립트에는 추상 메서드가 존재하지 않는 것으로 보인다. interface가 존재하지 않는다. 타입스크립트는 존재하는 것 같은데…
- 제한적이지만 나의 경우 다음과 같이 구현해보았다. 호출되는 런타임 시점에서 에러가 발생하는 한계를 지니지만, 일단 잘 동작한다.
class SuperClass{
static staticMethod(){
throw new Error("this method should be overridden");
}
instanceMethod(){
throw new Error("this method should be overridden");
}
}
직렬화와 역직렬화 serialization, deserialization,
- js의 객체에 대한 직렬화의 결과는 JSON 이다.
- JSON으로의 직렬화는 잘 동작하지만 역직렬화는 잘 동작하지 않는다. 역직렬화의 결과가 직렬화 한 클래스의 객체로 보장하지 않는다. 단순한 객체로 리턴한다.
- 이에 따라 다음과 같이 역직렬화를 위한 기능을 마련했다.
class School{
constructor(name) {
this.name = name;
}
static deserialize(json){
let obj = JSON.parse(json);
return new School(obj.name);
}
}
let school = new School("서울초");
let serialization = JSON.stringify(school);
let deserialization = JSON.parse(serialization);
let deserializedSchool = School.deserialize(serialization);
console.log(serialization);
console.log(school instanceof School); // true
console.log(deserialization);
console.log(deserialization instanceof School); // false
console.log(deserializedSchool instanceof School); // true
그 외
- class와 관련하여 메타데이터를 다음과 같은 형태로 추출할 수 있다.
class Tester {
constructor(name) {
this.name = name;
}
}
let tester = new Tester("kim");
console.log(tester.constructor.name); // Tester
나아가며
- class를 사용하는데 필요한 소박한 수준을 정리했다. 프론트엔드를 다루는데 함수나 객체로 한계가 있었고, 이를 해소하기 위하여 클래스를 학습 및 정리하였다.
- 함수를 통한 객체선언보다 클래스가 월등한 지점은 정적 메서드 구현에 있다고 본다. 직렬화와 역직렬화를 다루거나 factory pattern을 구현하기 위해서는 스태틱 메서드가 필요하기 때문이다.