자바스크립트 클래스 ?
자바스크립트는 엄밀이 말하면 클래스의 개념이 존재하지 않고, 프로토타입 기반으로 클래스처럼 사용할 수 있습니다.
예를 들어 Array 타입의 객체를 new 연산자를 통해 인스턴스를 생성하면, Array의 프로토타입 내부 요소들이 참조되는데, 이를 클래스 기반 언어의 상속과 비슷하다고 볼 수 있습니다.
ES5까지의 자바스크립트에서는 클래스가 없으며, ES6부터 프로토타입을 기반으로 클래스의 역할을 하는 기능이 도입되었습니다.
프로토타입 메서드 vs 스태틱 메서드
자바스크립트는 프로토타입을 활용해서 인스턴스가 접근 가능한 프로토타입 메서드와 접근 불가능한 스태틱 메서드로 나누어집니다.
const Rectangle = function (width, height) {
this.width = width;
this.height = height;
};
// 프로토타입 메서드 (인스턴스 접근 가능)
Rectangle.prototype.getArea = function() {
return this.width * this.height;
};
// 스태틱 메서드 (인스턴스 접근 불가능)
Rectangle.isRectangle = function (instance) {
return instance instanceof Rectangle &&
instance.width > 0 && instance.height > 0;
};
const rect = new Rectangle(3, 4);
console.log(rect.getArea()); // 12 - rect.__proto__ 의 getArea를 바라봄
// console.log(rect.isRectangle(rect)); // TypeError : is not a function
console.log(Rectangle.isRectangle(rect)); // true
(위의 코드는 ES5버전까지의 방식으로 밑에서 ES6 버전도 추가적으로 다루겠습니다.) Rectangle 객체를 만들어서 rect라는 인스턴스를 생성하였습니다.
rect.getArea() 메서드를 호출하면 rect 인스턴스는 rect.__proto__. getArea()를 호출하는데, __proto__를 생략하였으므로 Rectangle.prototype.getArea()를 호출하게 됩니다. 인스턴스에서 호출이 가능하므로 프로토타입 메서드입니다.
rect.isRectangle() 메서드는 호출하면 TypeError가 발생합니다. 호출 시 rect.__proto__ 타입에 메서드가 없고, Object 타입인 rect.__proto__.__proto__ 에도 메서드가 없기 때문에 함수를 실행할 수 없다는 오류가 발생합니다. 이와 같이 인스턴스에서 접근할 수 없도록 설계된 메서드가 스태틱 메서드입니다.
ES6 클래스 문법
ES6부터 프로토타입을 기반으로 클래스의 역할을 하는 기능이 도입되었습니다.
const Person = class {
constructor (name) { // const Person = function(name) {this.name = name}
this.name = name;
}
static staticMethod () { // Person.staticMethod = function(){}
return 'static method : ' + this.name;
}
method () { // Person.prototype.method = function() {}
return 'method : ' + this.name;
}
}
const personA = new Person('sasca');
console.log(Person.staticMethod()); // Person
console.log(personA.method()); // sasca
class라는 명령어를 통해서 중괄호({}) 내부에 클래스 본문 영역을 생성할 수 있습니다. 내부에 constructor, static, 메서드 형식을 지정할 수 있습니다. function 키워드를 생략하더라도 클래스 본문 영역에선 모두 메서드로 인식합니다.
ES6 extends 기능
const personA = new Person('sasca');
console.log(Person.staticMethod());
console.log(personA.method());
const KoreaPerson = class extends Person {
constructor (name) {
super(name);
}
getNationality() {
return 'Korea';
}
}
const koreaPersonA = new KoreaPerson('sasca');
console.log(KoreaPerson.staticMethod()); // KoreaPerson
console.log(koreaPersonA.method()); // sasca
console.log(koreaPersonA.getNationality()); // Korea
class extends 키워드를 사용하여 클래스 기반 언어에서 상속처럼 사용할 수 있습니다. Person을 상속받은 KoreaPerson 객체의 인스턴스는 Person의 기능을 자신의 것처럼 자유롭게 사용할 수 있습니다.