자바스크립트는 프로토타입 기반 객체지향 언어이다.
ES6부터는 클래스 기반 언어에 익숙한 프로그래머들을 위해 클래스 구문이 등장하였다. 사실 ES6의 클래스도 함수이며, 문법적 설탕(Syntactic sugar)일 뿐이지만, 기존 생성자 함수보다 클래스가 보다 엄격하기 때문에 단순한 문법적 설탕이라고 보지않는 견해도 있다.
1. ES5
객체 생성자 함수와 new 키워드, 프로토타입, 클로저를 통하여 클래스를 구현하였다.
var instance = {
prop1: init,
prop2: init,
method1: function () {
...
}
}
function Class(prop1,prop2) {
this.prop1 = prop1;
this.prop2 = prop2;
this.method1 = function () {
return this.prop1+this.prop2
}
}
var instance = new Class('test1','test2');
console.log(instance.method1())
// test1test2
function Class(prop1,prop2) {
this.prop1 = prop1;
this.prop2 = prop2;
}
var foo = new Class('test1','test2');
Class.prototype.method1 = function () {
return this.prop1+this.prop2
}
console.log(foo.method1());
함수 방식의 치명적인 단점으로는 내부 모든 메서드가 독립적으로 만들어지기 때문에 메모리 관리 적인 측면에서 좋지 않다.
2. ES6
프로토타입 기반 class 키워드를 지원한다.
일반함수는 constructor에 this 바인딩을 해줘야 하지만, 화살표함수는 this가 autobind다.
this.handleClick = this.handleClcik.bind(this) 할 필요가 없어짐
constructor 를 사용하면 다른 모든 메서드 호출보다 앞선 시점인, 인스턴스 객체를 생성하고, 클래스필드를 초기화할 때 수행할 초기화 코드를 정의할 수 있습니다.
super 생성자에서는 super 키워드 하나만 사용되거나 this 키워드가 사용되기 전에 호출되어야 합니다. 또한 super 키워드는 부모 객체의 함수를 호출하는데 사용될 수 있습니다.
extends 키워드는 내장 객체뿐만 아니라 사용자 정의 클래스를 하위 클래스로 만들기 위해 사용될 수 있습니다.
getter getter는 클래스 필드에 접근할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용한다.
setter setter는 클래스 필드에 값을 할당할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용한다.
static 메소드 클래스의 정적 메소드를 정의할때 사용한다. 이때 인스턴스를 생성하여 호출하는 것이 아닌, 클래스를 직접 호출 한다. 인스턴스를 호출할 수 없다는 것은 this를 사용할 수 없다는 것 이다. 즉, this를 사용할 필요 없는 유틸리티 메소드에서 주로 사용 된다.
오버라이딩 상위 클래스가 가지고 있는 메소드를 하위 클래스가 재정의하여 사용하는 방식이다.
오버로딩 매개변수의 타입 또는 갯수가 다른, 같은 이름의 메소드를 구현하고 매개변수에 의해 메소드를 구별하여 호출하는 방식이다. 자바스크립트는 오버로딩을 지원하지 않지만 arguments 객체를 사용하여 구현할 수는 있다.
class Polygon {
constructor(height, width) {
this.name = 'Polygon';
this.height = height;
this.width = width;
}
sayName() {
console.log('Hi, I am a ', this.name + '.');
}
}
class Square extends Polygon {
constructor(height, width) {
super(height, width);
this.name = 'Square';
this.height;
this.width;
}
get area() {
return this.height * this.width;
}
set area(value) {
this.height = value;
}
}
const square = new Square(300, 500);
class Test {
constructor(prop) {
this.prop = prop;
}
static getStatic() {
return 'thisIsStatic'
}
getProto() {
return this.prop;
}
}
console.log(Test.getStatic);
// thisIsStatic
const proto = new Test('proto');
console.log(proto.getProto())
// proto