본문 바로가기

Languages/JavaScript

[JavaScript] 클래스 정적 메서드와 정적 프로퍼티

728x90

 

 

   목차 

1. 정적 메서드란?
2. 정적 메서드 사용법
3. 일반 클래스로 정의된 메서드와 정적 메서드를 비교해보기 
4. 정적 메서드의 특징
5. 정적 메서드를 사용하는 경우 
6. 정적 메서드를 사용하면 안되는 경우 
7. 정적 메서드를 사용한 예제 

 

 

 

정적 메서드와 정적 프로퍼티에 대해서 알아보자! 

 

 

 


 

 

 

 

 1. 정적 메서드란? 

 

정적(static) 메서드클래스의 인스턴스가 아닌 클래스 자체에 속하는 메서드이다.

즉, 해당 클래스의 모든 인스턴스에서 공유되는 메서드이다. 

정적 메서드는 인스턴스의 상태를 변경하지 않으며, 주로 클래스와 관련된 유틸리티 기능을 제공하거나, 클래스의 동작을 수행하는 데 사용된다. 

 

 


 

 

 2. 정적 메서드 사용법 

 

정적 메서드는 아래와 같이 클래스 안에서 static 키워드를 붙여 만들 수 있다. 

class User {
  static staticMethod() {
    alert(this === User);
  }
}

User.staticMethod(); // true

 

정적 메서드는 메서드를 프로퍼티 형태로 직접 할당하는 것과 동일한 일을 한다.

class User { }

User.staticMethod = function() {
  alert(this === User);
};

User.staticMethod(); // true

 

User.staticMethod()가 호출될 때 this의 값은 클래스 생성자인 User 자체가 된다(.점 앞 객체)

 

 


 

 

 3. 일반 클래스로 정의된 메서드와 정적 메서드를 비교해보기 

 

일반 클래스(class)로 정의된 메서드 클래스의 인스턴스에서 호출할 수 있는 일반적인 메서드이다.
따라서 클래스의 인스턴스를 생성한 후에 메서드를 호출해야 한다.

class User {
  method() {
    alert(this === user); // true 
  }

  static staticMethod() {
    alert("This is a static method");
  }
}

let user = new User();

user.method(); // 일반 메서드 호출  // 호출 시 this는 user 인스턴스를 가리킨다. 
User.staticMethod(); // 정적 메서드 호출

 

위 코드에서 method() 메서드일반 클래스 메서드로 정의되어 있으며,
staticMethod()정적 메서드로 정의되어 있다. 


method() 메서드User 클래스의 인스턴스를 통해 호출되며, 해당 인스턴스에 의해 실행된다. 

반면에 staticMethod()User 클래스 자체에 속하며, 인스턴스를 생성하지 않고도 클래스 이름을 통해 직접 호출할 수 있다. 

일반 클래스 메서드와 정적 메서드는 서로 다른 용도로 사용되며, 적절한 상황에 따라 사용해야 한다.

 

 


 

 

 4. 정적 메서드의 특징 



 1) 클래스 레벨에서 호출됨 

정적 메서드는 클래스의 인스턴스가 아닌 클래스 자체에서 호출된다. 인스턴스를 생성하지 않고도 클래스의 이름을 사용하여 직접 호출할 수 있다.


 2) 인스턴스와 독립적 

정적 메서드는 클래스의 인스턴스와는 관련이 없으며, 인스턴스 속성이나 메서드에 접근할 수 없다. 따라서 정적 메서드 내에서는 this 키워드를 사용하여 클래스 자체를 가리키며, 인스턴스의 속성이나 메서드에는 접근할 수 없다. 



 3) 하위 클래스에 상속됨 

정적 메서드는 하위 클래스에 된다. 즉, 하위 클래스에서도 동일한 이름의 정적 메서드를 호출할 수 있다.

 

 


 

 

 5. 정적 메서드를 사용하는 경우 



 1) 클래스의 인스턴스와 무관한 동작을 수행할 때 

정적 메서드는 클래스의 인스턴스와 무관한 동작을 수행할 때 유용하다. 예를 들어, 수학 함수나 유틸리티 함수와 같이 특정 인스턴스에 종속되지 않는 기능을 구현할 때 정적 메서드를 사용한다.


 2) 클래스의 생성자 함수와 밀접한 관련이 있는 유틸리티 함수를 제공할 때 

정적 메서드는 클래스의 생성자 함수와 밀접한 관련이 있는 유틸리티 함수를 제공할 때 사용된다. 예를 들어, 생성자 함수의 인스턴스를 생성하는 데 사용되는 팩토리 메서드를 구현할 때 정적 메서드를 사용한다.

 

 


 

 

 6. 정적 메서드를 사용하면 안되는 경우 



 1) 인스턴스 속성에 의존하는 경우 

메서드가 인스턴스의 속성에 의존하거나 인스턴스의 상태를 변경해야 할 때는 정적 메서드를 사용하기 어렵다. 이러한 경우에는 일반 인스턴스 메서드를 사용하여 해당 인스턴스에 대한 작업을 수행하는 것이 더 적절하다. 예를 들어, 만약 메서드가 특정 인스턴스의 속성을 사용해야 한다면 해당 메서드를 인스턴스 메서드로 정의하는 것이 더 적합하다.

 

정적 메서드를 사용하여 인스턴스의 상태를 변경하려고 할 때 오류가 발생하는 예시

class Counter {
  constructor() {
    this.count = 0;
  }

  increment() {
    this.count++; // 인스턴스 속성 사용
  }

  static printCount() {
    console.log(this.count); // 오류 발생: 정적 메서드에서는 인스턴스 속성에 접근할 수 없음
  }
}

let counter = new Counter();
counter.increment();
Counter.printCount(); // 오류 발생

 

 

 2) 메서드가 클래스의 상태를 변경해야 하는 경우 

정적 메서드는 주로 클래스의 인스턴스와는 관련이 없는 동작을 수행해야 할 때 사용된다. 만약 메서드가 클래스 자체의 상태를 변경해야 한다면 정적 메서드를 사용하기 어렵다. 이 경우에는 일반 메서드를 사용하여 클래스의 상태를 변경하는 것이 적절하다.

class Config {
  constructor() {
    this.debugMode = false;
  }

  static enableDebugMode() {
    this.debugMode = true; // 오류 발생: 정적 메서드에서 클래스 상태 변경 시도
  }

  toggleDebugMode() {
    this.debugMode = !this.debugMode; // 클래스의 상태 변경
  }
}

let config = new Config();
config.toggleDebugMode(); // 클래스의 상태 변경
Config.enableDebugMode(); // 오류 발생

 

 


 

 

 7. 정적 메서드를 사용한 예제 

 

클래스를 사용하여 기사(Article)를 정의하고, 해당 기사들을 날짜(date)를 기준으로 정렬하는 예시

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

 

 

 과정 

 

 1) Article 클래스 정의 

  • Article 클래스는 constructor 메서드를 가지고 있다. 이 메서드는 기사의 제목(title)과 날짜(date)를 매개변수로 받아 인스턴스를 초기화한다. 즉, 기사를 생성할 때는 new Article("제목", 날짜)와 같은 형태로 생성한다.
  • title과 date는 인스턴스의 속성으로 저장된다.

 2) 정적(static) 메서드 compare 정의 

  • compare 메서드는 클래스의 정적 메서드로 선언되어 있다. 이는 클래스에 직접적으로 접근할 수 있는 메서드이다.
    따라서 클래스의 인스턴스를 생성하지 않고도 호출할 수 있다.
  • compare 메서드는 두 개의 기사(articleA, articleB)를 비교하여 날짜를 기준으로 정렬하기 위한 비교 함수이다.
    이 메서드는 두 기사의 날짜를 비교하여, articleA의 날짜가 articleB의 날짜보다 이전이면 음수를, 같으면 0을, 이후이면 양수를 반환한다.

 3) 기사 생성 

  • let articles = [...] 부분에서 기사를 생성한다. 각 기사는 new Article을 사용하여 생성되며, 제목과 날짜가 인수로 전달된다. 이 예시에서는 세 개의 기사를 생성하고 배열에 저장한다.

 4) 기사 정렬 

  • 생성된 기사 배열인 articles는 Array.prototype.sort() 메서드를 사용하여 날짜를 기준으로 정렬된다. 정렬할 때 Article.compare 메서드가 사용된다. 이 메서드는 비교 함수로서 날짜를 비교하여 정렬 기준을 제공한다.

 5) 결과 출력 

  • 정렬된 배열에서 첫 번째 기사의 제목을 출력한다. 이 예시에서는 alert( articles[0].title )을 사용하여 첫 번째 기사의 제목을 알림창으로 출력한다. 정렬 결과를 보면, 가장 이른 날짜를 가진 기사가 첫 번째로 출력된다.

 

 

 위 코드에서 static을 사용한 이유 

 

static 키워드를 사용하는 이유는 해당 메서드가 클래스 자체에 속하고, 인스턴스에 속하는 것이 아니기 때문이다. 클래스의 인스턴스와는 무관하게 클래스 레벨에서 독립적으로 동작해야 하는 메서드에 static 키워드를 사용한다. 따라서 Article.compare와 같이 클래스를 통해 직접 접근할 수 있으며, 인스턴스를 생성하지 않고도 사용할 수 있다.

여기서 compare 메서드는 기사를 비교하여 정렬할 때 필요한 비교 함수이다. 이 비교 함수는 클래스의 인스턴스와는 관련이 없고, 오로지 기사 객체들을 비교하는 데만 사용된다. 따라서 compare 메서드를 클래스의 인스턴스 메서드로 정의할 필요가 없는 것이다.

 

 


 

 

 8. 정적 프로퍼티 

 

정적 프로퍼티는 일반 클래스 프로퍼티와 유사하게 생겼는데 앞에 static이 붙는다는 점만 다르다.

class Article {
  static publisher = "Ilya Kantor";
}

alert( Article.publisher ); // Ilya Kantor

 

 


 

 

 9. 정적 프로퍼티와 메서드 상속 

 

정적 프로퍼티와 메서드는 상속된다.

클래스와 상속에 관련된 개념을 사용하여 간단한 동물(Animal)과 그 하위 클래스인 토끼(Rabbit)를 정의하고, 이들을 활용하는 예시를 살펴보자.

 

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); // 지구

 

 

 1) Animal 클래스 정의 

  • Animal 클래스는 동물의 기본 특성을 나타낸다.
  • static 키워드를 사용하여 planet 속성을 정의하고, "지구" 값을 할당했다. 이 속성은 모든 동물에 대해 공통적으로 적용되는 속성으로, 인스턴스가 아닌 클래스 자체에 속하는 정적 속성이다.
  • constructor 메서드는 동물의 이름(name)과 속도(speed)를 받아서 인스턴스를 초기화한다.
  • run 메서드는 동물이 달리는 것을 나타낸다. 속도를 변경하고, 그에 따라 메시지를 출력한다.
  • static compare 메서드는 두 동물의 속도를 비교하여 정렬할 때 사용되는 비교 함수이다.

 2) Rabbit 클래스 정의 

  • Rabbit 클래스는 Animal 클래스를 상속받는다. 즉, Rabbit는 Animal의 모든 기능과 속성을 상속받는다.
  • hide 메서드는 토끼가 숨는 동작을 나타낸다. 이 메서드는 Rabbit 클래스에만 존재하는 인스턴스 메서드이다.

 3) 토끼 인스턴스 생성 

  • let rabbits = [...] 부분에서 토끼 인스턴스를 생성한다. 각 토끼는 new Rabbit를 사용하여 생성되며, 이름과 속도가 인수로 전달된다.

 4) 토끼 정렬 

  • 생성된 토끼 배열인 rabbits를 Array.prototype.sort() 메서드를 사용하여 속도를 기준으로 정렬한다. 이때 Rabbit.compare 메서드가 사용된다. 이 메서드는 두 토끼의 속도를 비교하여 정렬에 사용된다.

 5) 토끼 달리기 및 지구 속성 출력 

  • 정렬된 배열에서 첫 번째 토끼(rabbits[0])의 run 메서드를 호출하여 달리게 한다.
  • Rabbit.planet을 통해 모든 토끼가 지구에 살고 있다는 정보를 확인한다.

이렇게 클래스와 상속을 사용하여 다양한 동물 객체를 생성하고, 이들을 활용하는 예시이다.
클래스와 상속은 객체 지향 프로그래밍에서 중요한 개념이며, 이를 통해 코드를 구조화하고 재사용성을 높일 수 있다.

 

 

 

 

728x90