타입스크립트로 작성한 코드를 보다 보니 class
를 굉장히 많이 사용한다는 생각이 들었다.
class
에서 Get, Set, Static, Public, Private
등의 키워드가 등장하는데 한번도 짚고 넘어간 적이 없는 것 같아 정리를 해보려 한다.
static methods
는 클래스를 위한 정적(static) 메소드를 정의하는데 사용한다. 이 메소드는 클래스의 인스턴스화 없이도 호출되며, 오히려 인스턴스에서는 호출할 수 없다.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
const distX = a.x - b.x;
const disY = a.y - b.y;
return Math.hypot(distX, distY);
}
}
const point1 = new Point(5, 5);
const point2 = new Point(10, 10);
point1.distance; // undefined;
point2.distance; // undefined;
Point.distance(point1, point2); // 7.0710678118654755
Point
라는 클래스에서 distance
메소드는 static
으로 정의되었다. 따라서 인스턴스에서 호출하게 되면 undefined
가 나오게 되며 Point
클래스에서 호출할 수 있다.
getter
메소드는 객체 안에서 어떤 프로퍼티에 접근할 때, 내부 변수의 상태를 명시적인 함수 호출 없이 보여주고 싶을 대 혹은 그 값을 계산하도록 해야 할 때 사용한다.
const obj = {
log: ["example", "test"],
get latest() {
return this.log.length === 0 ? undefined : this.log[this.log.length - 1];
}
};
console.log(obj.latest); // "test"
obj
라는 객체에 유사 프로퍼티인 latest가 있다. 이 프로퍼티는 log라는 프로퍼티의 마지막 요소를 반환한다. latest
에는 어떤 값을 할당하려고 해도 그 값이 바뀌지 않는다.
이미 존재하는 객체에 getter
를 추가하고 싶을 때는 Object.defineProperty()
를 사용하면 된다. 아래에 예시가 있다.
const obj = { a: 0 };
Object.defineProperty(obj, "b",
{ get: function () {
return this.a + 1; }
})
console.log(obj.b) // 0 + 1
Smart Getter
스마트 getter
는 프로퍼티의 값을 나중에 접근하기 위해 캐싱한다. 값은 getter
가 호출될 때 처음 계산되며 캐싱된다. 이후의 호출에는 다시 계산하지 않고, 캐시 값을 반환한다.
따라서 계산 비용이 큰 경우, 값의 이용 빈도가 낮을 경우, 값이 절대 변경되지 않을 경우에 사용하면 높은 효율을 낼 수 있다.
public
필드는 한번 선언되면 모든 인스턴스에 존재하며 사용할 수 있다. public static
필드는 static
이라는 키워드로 사용할 수 있는데, statie method
와는 다르다.
class Sample {
static field = "static field"
}
console.log(Sample.field); // "static field"
public
필드는 인스턴스 생성시에 추가되거나 super()
가 호출된 직후에 추가된다.
class Sample {
instanceField = "instance field";
}
const instance = new Sample();
console.log(instance.instanceField); //"instance field";
public
필드와는 다르게 public
메소드에서의 this
는 인스턴스를 바라본다. 상속 클래스의 다른 메소드를 사용하고 싶다면 super()
를 사용하여 부로 클래스의 constructor
를 호출하면 된다.
class Base {
greeting = "Hello";
greet() {
return this.greeting;
}
}
class Sub extends Base {
subGreet() {
return super.greet();
}
}
const instance = new Sub();
console.log(instance.subGreet()); // "Hello"