자바스크립트의 객체지향 프로그래밍을 알아봅시다!
자바스크립트에서 인스턴스를 생성하는 가장 기본적인 방법인 생성방법이다. 다른 포스트에서 다룬적이 있다.
function Func(a, b) {
this.a = a;
this.b = b;
}
Func.prototype.meth = function(){
console.log(this.a + this.b)
}
var inst = new Func(1, 2)
하도 많이 다뤘으니 자세한 설명은 생략하고 다른 포스트를 보자
function Func(a, b) {
var obj = {}
obj.a = a;
obj.b = b;
obj.meth = function(){
console.log(this.a + this.b)
}
return obj
}
var inst01 = Func(1, 2);
var inst02 = Func(3, 4);
inst01.meth()//3
inst02.meth()//7
ES6에 추가된 문법입니다! 자바나 다른 언어의 클래스가 아닙니다!
객체지향의 중심인 클래스를 자바스크립트에서 알아봅시다.
class Func{
constructor(a, b) {//(4.)
this.a = a;
this.b = b;
}
meth(){
console.log(this.a + this.b)
}
}
Func.c = 20;//(5.)
Func.prototype.d = 25;
const inst = new Func(1, 2);
이전의 생성자, 팩토리 함수와 같은 결과를 도출하지만 문법적으로 훨씬 깔끔해졌습니다. 기존의 변수들은 constructor라는 메서드에 넣고 기존 메서드들은 바깥에 작성합니다. 자바스크립트에 추가된 새로운 기능입니다. 하지만 그렇다고 해서 JS가 클래스를 지원하는것은 아닙니다?
console.log(typeof Func)// function (1.)
console.log(Func === Func.prototype.constructor)//true(2.)
console.log(Func.prototype)//Func{} 메서드 안나옴(3.)
클래스 문법 구조가 진짜 하는 일은 다음과 같습니다.
하지만 이전에 다뤘던 생성자함수를 통해 인스턴스를 생성했던 방법과 크게 다르지않습니다. 하지만 중요한 차이가 몇가지 있습니다.
console.log(Func)//console.log(Func)(2.)
static 키워드는 클래스를 위한 정적(static) 메서드를 정의합니다. 정적 메서드는 클래스의 인스턴스화(instantiating) 없이 호출되며, 클래스의 인스턴스에서는 호출할 수 없습니다.
class Func{
constructor(a, b) {
this.a = a;
this.b = b;
}
static meth01 = "method";
static meth02(){
console.log(this.a + this.b)
}
}
const inst = new Func(1, 2);
console.log(inst.meth01)//언디파인드
console.log(inst.meth02)//언디파인드
클래스에서의 "상속"기능은 어떻게 사용되는지 확인해보겠습니다. 객체지향 프로그래밍의 중요한 점 중 하나입니다.
class Func{
constructor(a, b) {
this.a = a;
this.b = b;
}
meth01(){
console.log(this.a + this.b)
}
}
class Child extends Func{
constructor(c) {
this.c = c;
}
meth01(){;
console.log("override")
}
meth02(){
console.log(`${this.a} is ${this.b}`)
}
}
const inst = new Child(1, 2);
inst.meth01()//override
inst.meth02()//error
프로토타입의 상속과 같은 결과를 도출합니다. 프로토타입의 상속은 Object.create쓰고 뭐 여러가지 해야할게 많았지만 class의 extend를 사용하니 훨씬 가독성이 좋아졌습니다.
여기서 만약 자식클래스에 동일명의 메서드가 존재하면 부모 클래스의 메서드에서 덮어씌어집니다.
이것을 메서드 오버라이딩이라고 합니다. 만약 부모의 메서드를 사용하고 싶을땐 super를 사용합니다.
meth01(){;
super.meth01()
console.log("override")
}
그리고 inst.meth02()를 호출하면 a, b가 존재하지않는다고 에러가 발생합니다. 에러문을 보면 자식 클래스에서 constructor를 호출할때 부모생성자를 반드시 호출해야한다고 나옵니다. 그리고 부모 constructor의 인수를 사용하려면 자식 constructor에서 부모 인수를 받아와야합니다.(아복잡다)
constructor(a, b, c) {
super(a, b);
this.c = c;
}
그런데 constructor를 만들지 않고 자식 클래스를 생성할 수도 있습니다. 그런 경우는
constructor(...arg) {
super(...arg);
}
이런 모양이 자동으로 생성됩니다.