정적 메서드(Static Method)란 인스턴스를 생성하지 않아도 호출할 수 있는 함수를 말합니다
클래스에만 종속된 함수이며, 인스턴스에 상속되지 않습니다
즉 인스턴스로는 정적 메서드에 접근할 수 없습니다
아래는 사용 예제입니다
class myClass {
// 함수명 앞에 static을 붙여서 정적 메서드를 생성할 수 있습니다
static staticMethod() {
console.log("이 친구는 정적 메서드");
}
}
MyClass.staticMethod(); // "이 친구는 정적 메서드"
let instance = new MyClass();
instance.staticMethod(); // Uncaught TypeError: instance.staticMethod is not a function
함수 생성과 호출을 모두 클래스에서...
정적 메서드는 클래스 자체와 관련된 기능을 수행하지만
따로 인스턴스를 생성할 필요가 없을 경우에 사용합니다
예를 들어 우리가 지금까지 사용해온 Date.now()
또한 Date 클래스의 정적 메서드입니다
별 생각없이 써왔는데... 이런 이유때문에 인스턴스 생성 없이도 현재 시간을 호출할 수 있었던 거군요
정적 메서드와 동적 메서드는 this
가 가리키는 대상이 달라질 수 있습니다
class Person {
// #이 붙은 size는 private 속성이 됩니다
// 특정 객체 정보를 console.log 등으로 드러내고싶지 않을 때 사용합니다
#size = 100
constructor(_name, _age) {
this.name = _name;
this.age = _age;
}
// 동적 메서드
getName() {
return this.name
}
// 정적 메서드
static getAge() {
console.log(this)
}
static getNameByClass(){
console.log(this.getName())
}
}
let person = new Person('Kim', 30);
console.log(person.getName()); // 'Kim'
Person.getAge(); // class Person
Person.getAge()
는 정적 메서드이므로 클래스(Person)를 가리킵니다person.getName()
는 동적 메서드로 호출될 때 인스턴스(name과 age값을 가진 객체)를 가리킵니다getNameByClass()
에서는 this.getName()
형식으로 메서드를 호출하며,아래 예제 코드에서 super.getName()
과 this.getName()
은 같은 기능을 하며,
양쪽 모두 "hello"를 반환합니다
하지만 각각이 가리키는 대상은 다릅니다
class Person {
constructor(_name, _age) {
this.name = _name;
this.age = _age;
}
static getName() {
return "hello"
}
}
class Man extends Person {
constructor(_age) {
super("Kim", _age)
}
static name () {
console.log(super.getName()) // hello
// super는 부모 클래스를 가리킵니다
// prototype인 Person까지 거슬러올라 getName 함수를 찾아서 실행합니다
console.log(this.getName()) // hello
// this가 가리키는 대상은 Man
// Pesrson 클래스에서 파생된 Man이 getName을 실행합니다
}
}
const Kim = new Man(20)
console.log(Man.name())
super
는 현재 클래스의 '부모 클래스'를 가리킵니다
그래서 위 예제코드에서 super.getName()
이 가리키는 대상은 Man이 아닌 Person 클래스입니다
*super
는 부모 클래스의 생성자를 호출하거나, 부모 클래스의 메서드에 접근할 때 사용합니다
반면 console.log(this.getName())
의this
는 현재 클래스인 Man을 가리킵니다
정적 메서드는 인스턴스에는 상속되지 않지만 자식 클래스에는 상속되기 때문입니다
직전 포스팅에서 define 메서드를 써서 만든 ORM 모델 생성함수를 클래스로 바꿔봅시다
[index]
const Sequelize = require("sequelize");
const config = require("../config");
const db = config.db[config.env];
const sequelize = new Sequelize(db.database, db.username, db.password, db);
// 소문자 sequelize는 인스턴스입니다
require("./comment.model")(sequelize, Sequelize);
// 인스턴스와 클래스를 인자로 모델 함수를 호출합니다
module.exports = {
sequelize,
Sequelize,
};
[comment.model]
module.exports = (sequelize, Sequelize) => {
class Comment extends Sequelize.Model {
static createTable() {
return this.init ({
// init은 define과 같은 기능을 하는 정적 메서드입니다
// 두 가지 인자(테이블의 필드 정보, 옵션)를 받습니다
userid: {
type: Sequelize.STRING(30),
allowNull: false,
},
content: {
type: Sequelize.TEXT(),
allowNull: false,
}
},
{
// init 메서드로 생성한 테이블 데이터를 아래 인스턴스에 전달해야 합니다
sequelize: sequelize
}
)
}
}
Comment.createTable() // 정적 메서드를 실행합니다
}
정리)
init
은 Sequelize 클래스에 내장된 정적 메서드로 테이블을 생성하는 기능을 합니다init
메서드는 인스턴스가 아닌 Comment 클래스에서 호출했다는 것!)init
을 통해 생성할 테이블 정보를 전달 받습니다createTable
)을 호출하면 init
메서드도 따라서 호출됩니다