class Counter { constructor() { this.counter = 0; } // 생성자 increase (){ this.counter ++; console.log(this.counter); } } const coolCounter = new Counter(); coolCounter.increase();
위의 기본적인 클래서 생성 코드에서 counter 가 5가 될때마다 알려주고싶으면 어떻게 처리를 할까 ?
class Counter { constructor() { this.counter = 0; } increase (){ this.counter ++; console.log(this.counter); if(this.counter %5 === 0){ console.log ('5의 배수 ! '); } } } const coolCounter = new Counter(); coolCounter.increase();
위와 같이 처리하면 Counter 클래스 자체에서 리턴하는 값을 조절하기 때문에, coolCounter (Object)를 쓰는사람은 다른 문구를 출력하거나 다른 행동을 취할 수 없다 ! 🚫
그럼 콜백함수를 Object 입장에서 전달할 수 있도록 다시 만들어보자.
class Counter { constructor() { this.counter = 0; } increase (runIf5Times){ this.counter ++; console.log(this.counter); if(this.counter %5 === 0){ runIf5Times(this.counter); } } } const coolCounter = new Counter(); function printSomething (num){ console.log(`yo! ${num}`); } coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething);
위 코드처럼 처리하면 Object 입장에서 출력하고싶은 문구가 담긴 콜백함수를 전달할 수 있고, 클래스로부터 값도 받아올 수 있다.
이렇게 했을 때의 장점은 오브젝트에서 콜백함수를 전달함으로써 원하는 기능을 수행할 수 있다.
const coolCounter = new Counter(); function printSomething (num){ console.log(`yo! ${num}`); } function alertNum(num){ alert(`wow! ${num}`); } coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(printSomething); coolCounter.increase(alertNum); // 다른 콜백도 전달이 가능
즉, 클래스 Counter 라는거 자체는 숫자가 5가 될때마다 어떤 기능을 수행하는지는 정해져있지 않다. 사용자가 원할때 필요한 기능을 전달하여 수행한다.
상기 코드와 같이 처리했을때의 문제점은 ??🤔 increase() 라는 함수를 호출할때마다 콜백함수를 넘겨야하므로 너무 불편하다..
class Counter { constructor(runEveryFivetimes) { this.counter = 0; this.callback = runEveryFivetimes; } increase (){ this.counter ++; console.log(this.counter); if(this.counter %5 === 0){ this.callback(this.counter); } } } function printSomething (num){ console.log(`yo! ${num}`); } function alertNum(num){ alert(`wow! ${num}`); } const coolCounter = new Counter(printSomething); coolCounter.increase();
그래서 위와 같이 보통은 오브젝트 생성시 (constructor) 에 콜백함수를 받는다.
만약 사용자가 콜백함수를 등록하지 않으면 어떻게 될까 ? 생성자에서 넘겨받아야할 ‘runEveryFiveTimes’는 undefined가 될것이고, increase() 함수에서 사용이 불가능할 것이다. 타입스크립트에서는 function? 처럼 question mark로 필수인지 아닌지를 정할수있는데, 자바스크립트는 그런게 없다 ..
그래서 사용자가 콜백함수를 전달하지 않았을때를 대비하여 아래와 같이 쓰면 된다.
class Counter { constructor(runEveryFivetimes) { //runEveryFiveTimes undefined this.counter = 0; this.callback = runEveryFivetimes; } increase (){ this.counter ++; console.log(this.counter); if(this.counter %5 === 0){ this.callback && this.callback(this.counter); // 한줄로 쓰는 방법 // if(this.callback){ // this.callback(this.counter); // } } } } function printSomething (num){ console.log(`yo! ${num}`); } function alertNum(num){ alert(`wow! ${num}`); } const coolCounter = new Counter(); // 1. 콜백함수를 전달 하지 않음. coolCounter.increase();
즉, 하나의 클래스 다양한 서로 다른 기능을 수행하는 오브젝트들을 만들 수 있다.
그럼 클래스의 재사용 가능성이 높아진다 😀
가능하면 class를 완전한 상태로 만드는 것 보다, 레고를 조립하는 것 처럼 사용자가 원하는 기능을 끼워서 재조립이 가능하도록 만드는게 좋다! ✅