[JavaScript] 콜백 함수로 재사용가능한 class 만들기

iberis2·2023년 1월 13일
0

용어정리

  • callback 함수 : 다른 함수의 파라미터로 들어가는 함수
  • 파라미터(parameter) : 함수에 지정된 매개변수
  • 아규먼트(argument) : 함수를 호출할 때 전달하는 전달인자
    argument가 함수의 parameter 자리로 전달된다.
  • 프로퍼티(property) : 이름(name 또는 key)과 값(value)으로 이루어진 한 쌍의 객체의 속성 (배열에서의 요소(element)와 같다)
  • 매서드(method): 객체의 프로퍼티 값으로 들어있는 함수
  • 인스턴스 객체(instance object) : class의 속성과 매서드를 바탕으로 만들어진 객체

클래스의 매서드

ES6 에서는 class 블록 안에 function 키워드 없이 바로 정의할 수 있다.

class Calculator {
  constructor() {
    this.value = 0;
  }

  increase() {   			// Calculator 클래스의 매서드
    this.value++;
    console.log(this.value);
  }
}

const myCalculator = new Calculator();
console.log(myCalculator); // Calculator { value: 0 }
myCalculator.increase();   // 1

만약 숫자가 5의 배수가 될 때마다 특정 문구를 함께 출력하고 싶다면?

1. 매서드에 직접 추가

class Calculator {
  constructor() {
    this.value = 0;
  }

  increase() {
    this.value++;
    this.value % 5 === 0
      ? console.log(`oh! it's ${this.value}`)
      : console.log(this.value);
  }
}

const myCalculator = new Calculator();
console.log(myCalculator); // Calculator { value: 0 }
myCalculator.increase();  // 1
myCalculator.increase();  // 2
myCalculator.increase();  // 3
myCalculator.increase();  // 4
myCalculator.increase();  // oh! it's 5

하지만 이 방법은 Counter class 자체에서 들어있는 매서드이니, 인스턴스 객체(instance object)인 myCalculator를 사용하는 사람이 컨트롤 할 수 없다.

클래스의 매서드와 콜백함수

2. 인스턴스 객체(instance object)의 아규먼트(argument)로 함수 전달

사용하고 싶은 함수를 클래스 외부에 선언하고, 호출하는 매서드의 아규먼트(argument)로 함수를 전달하여(=콜백함수), 매서드가 작동할 때, 함수도 함께 작동하도록 할 수 있다.

매서드가 해당 아규먼트(argument)를 활용할 수 있도록 파라미터가 정의되어 있어야한다.
만약 해당 인스턴스객체(instance object)의 프로퍼티(property)도 사용하고 싶다면, 프로퍼티(property) 값은 매서드 안에서 지정해주어야 한다.

class Calculator {
  constructor() {
    this.value = 0;
  }

  increase(add5Times) {
    this.value++;
    this.value % 5 === 0 
      ? add5Times(this.value)  // myCalculator의 property값을 활용하고 싶다면 매서드 안에서 지정해주어야 한다.
      : console.log(this.value);
  }
}


function printOh(num) { // this.value를 받아서 활용하기 위해 파라미터를 지정
  console.log(`oh! it's ${num}`);
}

const myCalculator = new Calculator();
console.log(myCalculator); // Calculator { value: 0 }
myCalculator.increase(printOh); // 1
myCalculator.increase(printOh); // 2
myCalculator.increase(printOh); // 3
myCalculator.increase(printOh); // 4
myCalculator.increase(printOh); // oh! it's 5

하지만 매번 콜백 함수를 전달해주어야해서 번거롭다.

class의 생성자 함수(cnstructor)와 콜백함수

3. class의 생성자 함수(constructor)에 콜백 함수를 파라미터로 받아서 객체의 프로퍼티로 지정

생성자 함수(constructor)의 파라미터(parameter)를 하나의 프로퍼티(property) 값으로 지정해 놓고, 매서드를 실행할 때 해당 프로퍼티(property)를 불러와 함수를 실행할 수 있다.
이 경우 인스턴스객체(instance object)를 생성할 때 전달하는 아규먼트(argument)가 프로퍼티 값으로 지정된다.

장점
콜백함수를 이용해서 클래스를 만들면 해당 클래스를 사용하는 사람이 인스턴스 객체를 생성할 때마다 원하는 대로 컨트롤이 쉽다.
즉, 수정이 용이하고 재사용하기 쉽다.

class Calculator {
  constructor(add5Times) {
    this.value = 0;
    this.callback = add5Times;
  }

  increase() {
    this.value++;
    this.value % 5 === 0 ? this.callback(this.value) : console.log(this.value);
  }
}

function printOh(num) {
  console.log(`oh! it's ${num}`);
}

const myCalculator = new Calculator(printOh);
console.log(myCalculator); // Calculator { value: 0, callback: [Function: printOh] }
myCalculator.increase(); // 1
myCalculator.increase(); // 2
myCalculator.increase(); // 3
myCalculator.increase(); // 4
myCalculator.increase(); // oh! it's 5


// 다른 함수를 콜백함수로 하는 다양한 인스턴스 객체를 만들 수 있다.
function alertNum(num){
  alert(`it's ${num}`);
}
const alertCalculator = new Calculator(alertNum); // value가 5가 되면 팝업 창이 나타남

단, 생성자 함수에 파라미터(parameter)를 지정하고, 매서드에서 함수를 호출했는데,
새로운 인스턴스 객체(instance object)를 만들 때 아규먼트(argument)로 함수를 전달하지 않으면 TypeError가 발생하기 때문에, 콜백함수가 있을 때만 해당 함수를 실행하도록 코드를 주의해서 작성해야한다.

class Calculator {
  constructor(add5Times) {
    this.value = 0;
    this.callback = add5Times;
  }

  increase() {
    this.value++;
    if (this.value % 5 === 0) { 
      // callback 이 true일 때 callback 함수 작동, callback이 false(undefined)이면 console.log 실행
      this.callback ? this.callback(this.value) : console.log(this.value);
    } else {
      console.log(this.value);
    }
  }
}

function printOh(num) {
  console.log(`oh! it's ${num}`);
}

const myCalculator = new Calculator();
console.log(myCalculator); // Calculator { value: 0, callback: undefined }
myCalculator.increase(); // 1
myCalculator.increase(); // 2
myCalculator.increase(); // 3
myCalculator.increase(); // 4
myCalculator.increase(); // 5
profile
React, Next.js, TypeScript 로 개발 중인 프론트엔드 개발자

0개의 댓글