티스토리 뷰
9.3 Static properties and methods
prototype이 아닌 클래스 자체적으로 메서드를 설정할 수 있다?(아마도 프로토 타입은 인스턴스가 생성될 때만 동작하는 것 같다.)
static 키워드를 붙여 만들 수 있고, 이를 정적 메서드라고 부른다. 어떤 객체가 아닌 클래스 전체에 활용될 수 있는 함수를 구현하고자 할 때 쓰인다.
아래 Article 간의 비교를 위한 메서드가 그 예시다.
class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static compare(articleA, articleB) {
return articleA.date - articleB.date;
}
}
// 사용법
let articles = [
new Article("HTML", new Date(2019, 1, 1)),
new Article("CSS", new Date(2019, 0, 1)),
new Article("JavaScript", new Date(2019, 11, 1))
];
articles.sort(Article.compare);
alert( articles[0].title ); // CSS
아래는 Article을 생성할 때, 팩토리 메서드 패턴을 위해 static 메서드를 활용한 경우다.
class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static createTodays() {
// this는 Article입니다.
return new this("Today's digest", new Date());
}
}
let article = Article.createTodays();
alert( article.title ); // Today's digest
static properties
말 그대로 static이 붙은 속성을 의미한다.
class Article {
static publisher = "Ilya Kantor";
}
alert( Article.publisher ); // Ilya Kantor
// ----------------
Article.publisher = "Ilya Kantor";
Inheritance of static properties and methods
정적 프로퍼티와 메서드도 상속이 된다.
class Animal {
static planet = "지구";
constructor(name, speed) {
this.speed = speed;
this.name = name;
}
run(speed = 0) {
this.speed += speed;
alert(`${this.name}가 속도 ${this.speed}로 달립니다.`);
}
static compare(animalA, animalB) {
return animalA.speed - animalB.speed;
}
}
// Animal을 상속받음
class Rabbit extends Animal {
hide() {
alert(`${this.name}가 숨었습니다!`);
}
}
let rabbits = [
new Rabbit("흰 토끼", 10),
new Rabbit("검은 토끼", 5)
];
rabbits.sort(Rabbit.compare);
rabbits[0].run(); // 검은 토끼가 속도 5로 달립니다.
alert(Rabbit.planet); // 지구
Java에서 static 키워드가 붙은 요소에 대해 클래스 영역에 따로 저장되기 때문에, 상속과는 별개로 직접 접근이 가능한 걸로 알고 있는데 javascript는 상속에 초점이 맞춰져 있는 느낌이다. 이 부분은 다시 살펴봐야겠다.
9.4 Private and Protected properties and methods
이번 장은 Java에서는 접근제어자와 같은 개념인데, 추상적인 설명은 제외하고 실제 언어에서 어떻게 필드의 접근을 제어하는지만 살펴보자.
Protecting "waterAmount"
class CoffeeMachine {
waterAmount = 0; // 물통에 차 있는 물의 양
constructor(power) {
this.power = power;
alert( `전력량이 ${power}인 커피머신을 만듭니다.` );
}
}
// 커피 머신 생성
let coffeeMachine = new CoffeeMachine(100);
// 물 추가
coffeeMachine.waterAmount = 200;
waterAmount를 내부에서만 다룰 수 있는 속성으로 취급하고 싶을 때, 이를 proected로 바꾸면 된다. javascript에서는 컨벤션으로 밑줄 '_'을 붙여 proteced를 표현한다. (javascript에서 강제하는 것이 아니다.)
class CoffeeMachine {
_waterAmount = 0;
set waterAmount(value) {
if (value < 0) throw new Error("물의 양은 음수가 될 수 없습니다.");
this._waterAmount = value;
}
get waterAmount() {
return this._waterAmount;
}
constructor(power) {
this._power = power;
}
}
// 커피 머신 생성
let coffeeMachine = new CoffeeMachine(100);
// 물 추가
coffeeMachine.waterAmount = -10; // Error: 물의 양은 음수가 될 수 없습니다.
read-only "power"
경우에 따라, getter 메서드만 구현하여 읽기 전용으로 만들 수도 있겠다.
class CoffeeMachine {
// ...
constructor(power) {
this._power = power;
}
get power() {
return this._power;
}
}
// 커피 머신 생성
let coffeeMachine = new CoffeeMachine(100);
alert(`전력량이 ${coffeeMachine.power}인 커피머신을 만듭니다.`); // 전력량이 100인 커피머신을 만듭니다.
coffeeMachine.power = 25; // Error (setter 없음)
// --------------------
// 아래처럼 get, set 키워드를 쓰지 않고 메서드를 만들 수도 있다.
class CoffeeMachine {
_waterAmount = 0;
setWaterAmount(value) {
if (value < 0) throw new Error("물의 양은 음수가 될 수 없습니다.");
this._waterAmount = value;
}
getWaterAmount() {
return this._waterAmount;
}
}
new CoffeeMachine().setWaterAmount(100);
private "#waterLimit"
javascript에서 클래스 내부에서만 접근할 수 있도록 강제하는 문법이다.
class CoffeeMachine {
#waterLimit = 200;
#checkWater(value) {
if (value < 0) throw new Error("물의 양은 음수가 될 수 없습니다.");
if (value > this.#waterLimit) throw new Error("물이 용량을 초과합니다.");
}
}
let coffeeMachine = new CoffeeMachine();
// 클래스 외부에서 private에 접근할 수 없음
coffeeMachine.#checkWater(); // Error
coffeeMachine.#waterLimit = 1000; // Error
private으로 waterAmount 속성을 가지고 있어도 public waterAmount 속성을 가질 수 있다.
상속받은 클래스에서는 접근이 안된다. 또한, 내부에서도 this[name] 형식으로 접근이 되지 않는다.
class MegaCoffeeMachine extends CoffeeMachine {
method() {
alert( this.#waterAmount ); // Error: CoffeeMachine을 통해서만 접근할 수 있습니다.
}
}
// --------
class User {
...
sayHi() {
let fieldName = "name";
alert(`Hello, ${this[fieldName]}`);
}
}
'스터디 > JavaScript' 카테고리의 다른 글
모던 자바스크립트 튜토리얼 part1 - 8.1 (0) | 2024.05.24 |
---|---|
모던 자바스크립트 튜토리얼 part1 - 9.6 ~ 7 (0) | 2024.05.24 |
모던 자바스크립트 튜토리얼 part1 - 9.2 (0) | 2024.05.24 |
모던 자바스크립트 튜토리얼 part1 - 9.1 (0) | 2024.05.23 |
모던 자바스크립트 튜토리얼 part1 - 5.12 (0) | 2024.05.21 |