✍️ 클래스와 콜백 알아보기
1. 숫자가 0부터 1씩 증가하다가, 5배수가 될 때마다 알려주는 카운터 클래스 만들기
class Counter {
constructor(){
this.counter = 0; // 필드
}
increase() { // 증가되는 increase 함수
this.counter++;
console.log(this.counter);
if(this.counter % 5 ===0 ){ // 5배수일 때마다 알리기
console.log('check!')
}
}
}
const coolCounter = new Counter();
coolCounter.increase(); // 1
coolCounter.increase(); // 2
coolCounter.increase(); // 3
coolCounter.increase(); // 4
coolCounter.increase(); // 5 // check!
coolCounter.increase(); // 6
✍️ MEMO
counter
라는 변수가 있다.object
를 만드는 순간 '0'으로 초기화가 된다.function
이라고 따로 작성하지 않아도 된다.increase()
함수를 호출할 때마다 카운터의 숫자를 하나씩 증가 시킨다.coolCounter
라는 변수에 클래스를 이용해서(new연산자 이용) 오브젝트를 만든다.constructor
가 실행되고 this.counter
를 '0'으로 초기화 한다.→ Counter라는 클래스 안에는 counter
변수, increase
함수가 있다.
→ coolCounter
변수는, 만들어진 오브젝트를 가르키고 있고, 그 오브젝트에 increase()
함수를 호출할 때마다 클래스 안에 있는 카운터라는 데이터가 하나씩 증가한다.
❓ 문제점
coolCounter
를 쓰는 사람이 원하는대로 세밀하게 조절하기 힘들다.2. 콜백함수를 통해서, 사용자 필요에 따라 출력을 컨트롤 할 수 있도록 만들기
class Counter {
constructor(){
this.counter = 0; // 필드
}
increase(runIf5Times) { // 증가되는 increase 콜백함수
this.counter++;
console.log(this.counter);
if(this.counter % 5 ===0 ){ // 5배수일 때마다 알림
runIf5Times(this.counter); // 숫자를 정확히 알기 위해서 this.counter
}
}
}
const coolCounter = new Counter();
function printSomething(num) { // 콘솔출력 함수
console.log(`${num} : hello !`);
}
function alertSomething(num){ // 팝업알림 함수
alert(`${num} : Hi~`);
}
coolCounter.increase(printSomething); // 1
coolCounter.increase(printSomething); // 2
coolCounter.increase(printSomething); // 3
coolCounter.increase(printSomething); // 4
coolCounter.increase(printSomething); // 5 // 5 : hello !
coolCounter.increase(alertSomething); // 6
coolCounter.increase(alertSomething); // 7
coolCounter.increase(alertSomething); // 8
coolCounter.increase(alertSomething); // 9
coolCounter.increase(alertSomething); // 10 // 10 : Hi~ 팝업창이 뜸
✍️ MEMO
increase
에 콜백함수 runIf5Times
를 받고 if
문을 통해 원할 때 출력 받을 수 있도록 작성한다.runIf5Times(this.counter)
를 통해서 인자를 전달하고, 각각의 함수에서 그 인자를 전달 받아서 출력한다.❓ 장점
printSomething
대신 alertSomething
함수를 새로 정의함으로써, 팝업알림도 받을 수 있게 되었다.→ 콜백함수를 전달함으로써 원하는 기능을 수행할 수 있게 되었다.
→ class Counter
라는 것은 숫자가 5배가 될 때마다 어떤 동작을 하는지는 자체적으로 결정되어있지 않다. 그래서 사용자가 원할 때 원하는 함수를 전달하게 되면 그것에 맞춰서 수행되어진다.
❓ 문제점
3. 클래스에 원하는 콜백함수를 전달하도록 만들기
class Counter {
constructor(runEveryFiveTimes){ // 콜백함수를 받도록 수정
this.counter = 0;
this.callback = runEveryFiveTimes; // callback 변수에 할당
}
increase() {
this.counter++;
console.log(this.counter);
if(this.counter % 5 ===0 ){
this.callback(this.counter);
}
}
}
function printSomething(num) { // 콘솔출력 콜백함수
console.log(`${num} : hello !`);
}
function alertSomething(num){ // 팝업알림 콜백함수
alert(`${num} : Hi~`);
}
const coolCounter = new Counter(printSomething); // 콜백함수 전달
// const coolCounter = new Counter(alertSomething);
coolCounter.increase(); // 1
coolCounter.increase(); // 2
coolCounter.increase(); // 3
coolCounter.increase(); // 4
coolCounter.increase(); // 5 // 5 : hello !
coolCounter.increase(); // 6
coolCounter.increase(); // 7
coolCounter.increase(); // 8
coolCounter.increase(); // 9
coolCounter.increase(); // 10 // 10 : hello !
✍️ MEMO
constructor
에서 콜백 함수를 받을 수 있도록 작성한다.constructor
함수 이므로 인자를 받아와서 함수내에서 작동(기억)되도록 callback
이라는 변수에 runEveryFiveTimes
를 할당한다.increase
함수의 if
문에서 callback
변수를 통해 콜백을 받아올 수 있으며, increase
함수를 호출할때 인자를 적지 않아도 된다.new Counter
생성자에 원하는 콜백함수를 전달한다.increase
가 호출 될 때마다 if
문의 조건이 만족되면 this.callback
함수를 호출한다. 호출할 때 카운터 안에있는 (this.counter)
데이터를 전달한다.this.callback
은 printSomething
을 가리키고 있기 때문에 이 함수가 수행된다.→ Counter 안에는 두가지의 데이터 타입이 들어가게 되었다. (1) counter
를 0으로 초기해주는 변수 (2)callback
변수
→ coolCounter
라는 오브젝트로 Counter라는 클래스의 청사진을 이용해서 오브젝트를 만들었는데, (1)counter
는 그대로 0을 가르키고, (2)callback
은 printSomething
을 가리킨다.
❓ 문제점
만약 const coolCounter = new Counter(printSomething);
에서 printSomething
이라는 콜백함수를 전달하지 않는다면 에러가 발생한다.
Counter라는 클래스는, 클래스를 만들때 콜백함수를 하나 전달 받는다. 그래서 new Counter()
를 통해서 카운터를 만들때, 어떤 콜백을 전달할지 지정하지 않으면, counstructor
의 인자는 undefined
가 된다. 결국 클래스 내부의 this.callback
은 undefined
가 된다.
실행시키면 TypeError 가 뜬다. this.callback
은 undefined
이고, 이것은 function
이 아니기 때문이다.
그래서 this.callback
이 undefined
or true
확인 후, 콜백을 부르도록 만들어야한다.
4. 클래스를 만들 때, 사용자가 콜백함수를 등록하면 호출되고, 등록된 콜백함수가 없다면 호출해서는 안되도록 만들기
increase() {
this.counter++;
console.log(this.counter);
// this.callback && this.callback(this.counter); 간단하게 작성할 경우
if(this.counter % 5 ===0 ){
if(this.callback){
this.callback(this.counter);
}
}
}
}
✍️ MEMO
AND 연산자 &&
AND 연산자 &&
를 if
문을 ‘짧게’ 줄이는 용도로 사용할 수 있는데, &&의 오른쪽 피연산자는 평가가 && 우측까지 진행되어야 실행된다.
즉, 여기서는 좌측이 true
인 경우에만 this.callback(this.counter)
문이 실행된다.
&&
를 사용한 코드가 더 짧지만, if
문을 사용한 예시가 코드에서 무엇을 구현하고자 하는지 더 명백히 드러내고, 가독성도 좋다고 한다. 그러므로 때에 따라서 if
조건문이 필요하면 if
를 사용하고, AND 연산자는 연산자 목적에 맞게 사용하는 것이 좋다고 한다. 🤔
✍️ MEMO
- 클래스에 원하는 기능을 다 정의하게 되면, 사용자가 세밀하게 컨트롤하거나 재사용성이 떨어진다.
- 콜백함수를 이용해서 클래스를 정의하게 되면, 사용자가 원하는대로 호출할 수 있다.
- 하나의 클래스로 다양한 오브젝트를 만들어서 서로 다른 기능을 수행할 수 있도록 작성한다면, 재사용성이 높아진다.
- 클래스를 모든 기능을 수행하는 완전체로 만들기 보다는 원하는 기능을 끼워 맞춰서 재조립이 가능하도록 만드는 것이 포인트이다. 😀