• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

계산하기 함수의 고차함수 응용

24.01.16 14:14 작성 조회수 215

1

const calculate = (op) => ()=> {
  if(numTwo){
    let num1 = Number(numOne);
    let num2 = Number(numTwo);
    switch (op) {
      case ('+'):
        $result.value = num1+num2;
        break;
      case ('-'):
        $result.value = num1-num2;
        break;
      case ('/'):
        $result.value = num1/num2;
        break;
      case ('*'):
        $result.value = num1*num2;
        break;
    }
    $operator.value = ''
  }
  else{
    alert('두번째 숫자를 입력해주세요!')
  }
}

document.querySelector('#calculate').addEventListener('click', calculate(operator))

고차 함수 개념을 한번 적용해 보고자 calculate함수를 고차함수를 이용해서 한번 작성해 보았습니다. 하지만
op라는 매개변수를 calculate함수 안에서 console.log 해보았을때 제대로 불러지지 않는데 이유가 무엇인지 궁금합니다.
operator와 numOne numTwo를 모두 누른 상태를 가정하고 싶습니다.

답변 2

·

답변을 작성해보세요.

0

김민서님의 프로필

김민서

질문자

2024.01.17

const calculate = (op) => () => {
  console.log(op)
  if (numTwo) {
    let num1 = Number(numOne);
    let num2 = Number(numTwo);
    switch (op) {
      case ('+'):
        $result.value = num1 + num2;
        break;
      case ('-'):
        $result.value = num1 - num2;
        break;
      case ('/'):
        $result.value = num1 / num2;
        break;
      case ('*'):
        $result.value = num1 * num2;
        break;
    }
  }
  numOne = $result.value
  numTwo = ''
}

document.querySelector('#calculate').addEventListener('click', calculate(operator))

콘솔로그는 calculate함수 가장 상단에 넣었습니다.
고차함수를 이용해서 이벤트리스너에 함수의 리턴값을 주기위해 calculate(operator)를 하였고
operator는 기존 강사님께서 알려주신 함수와 동일합니다.
일반적으로 numOne을 클릭하고 operator를 누른뒤에 numTwo 누르고 calculate버튼을 누르니
document.querySelector('#calculate').addEventListener('click', calculate(operator))
이부분에서 operator에 올바르게 입력한 연산자가 인수로 주어진다 생각했는데
작동하지 않는 원인을 모르겠습니다 ㅠㅠ

김민서님의 프로필

김민서

질문자

2024.01.17

계산 또한 되지않습니다

전체적인 코드 순서가 잘못된 거 아닌가요? 단순히 저 코드만 봤을 때는 문제가 없습니다.

김민서님의 프로필

김민서

질문자

2024.01.17

원인을 못찾겠습니다 ㅠㅠ console.log에 operator가 제대로 전달이 안되는 것 같은데
염치없지만 전체적인 코드 한번만 봐주실 수 있을까요?

let numOne = '';
let numTwo = '';
let operator = '';

const $operator = document.querySelector('#operator');
const $result = document.querySelector('#result');
const clickNum = (event) => {
  console.log(event.target.textContent);
  if (!operator) { // 첫번째 숫자가 눌렸을 때 
    numOne += event.target.textContent;
    $result.value += event.target.textContent;
    return;
  }

  $result.value = '';


  numTwo += event.target.textContent;
  $result.value += event.target.textContent;
}

const clickOperator = (op) => () => {
  if (numOne && numTwo) { // 계산을 이어서 하고자 할 때 
    calculate()
    numOne = $result.value
    numTwo = '';
    operator = op;
    $operator.value = op;

  }
  if (numOne) { // numOne을 입력하고 연산자를 클릭했을 때 
    operator = op;
    $operator.value = op;
  }
  else { // numOne 조차 입력 안했을 때 
    alert('숫자를 먼저 입력하세요 ')
  }
}

const calculate = (op) => {
  if (numTwo) {
    let num1 = Number(numOne);
    let num2 = Number(numTwo);
    switch (op) {
      case ('+'):
        $result.value = num1 + num2;
        break;
      case ('-'):
        $result.value = num1 - num2;
        break;
      case ('/'):
        $result.value = num1 / num2;
        break;
      case ('*'):
        $result.value = num1 * num2;
        break;
    }
  }
  numOne = $result.value
  numTwo = ''
}



document.querySelectorAll('.num').forEach(element => {
  element.addEventListener('click', clickNum)
});


document.querySelector('#plus').addEventListener('click', clickOperator('+'))
document.querySelector('#minus').addEventListener('click', clickOperator('-'))
document.querySelector('#divide').addEventListener('click', clickOperator('/'))
document.querySelector('#multiply').addEventListener('click', clickOperator('*'))
document.querySelector('#calculate').addEventListener('click', calculate(operator));
document.querySelector('#clear').addEventListener('click', () => {
  numOne = ''
  numTwo = ''
  operator = ''
  $operator.value = ''
  $result.value = ''
})


아 알았습니다. calculate(operator)할 때 이미 operator가 초기값인 ''로 고정되어버리네요.

애초에 고차함수를 응용할 수 있는 코드가 아닙니다. operator는 변하는 값이라서요

김민서님의 프로필

김민서

질문자

2024.01.17

혹시 조금만 더 설명해주실 수 있을까요?
calculate라는 id를 가진 dom객체는 아무래도 숫자계산을 하기위해

numOne과 operator와 numTwo에 모두 클릭한 값이 변수에 들어있는 것 이라 생각했는데
왜 operator가 초기값인 ''로 고정되버리는 것인지 잘 이해가 안됩니다 ㅠㅠ

함수는 호출되는 순간 매개변수로 넣은 값이 고정됩니다. calculate 클릭 이벤트는 코드 실행 시 바로 생성되므로 그 때의 operator값이 고정됩니다. operator를 아무리 변경해도 그 뒤에 클릭 이벤트를 다시 생성하는 게 아니라 그 전에 생성한 클릭 이벤트가 도는 겁니다.

let a =1

const b = 2

const c = a+b

a = 4

를 한다고 해서 c가 6이 되는게 아니라 계속 3인 것과 마찬가지인거죠.

calculate(operator)는 실행되는 순간 calculate('')인 겁니다. 그렇게 고정되는 것이고요. clickOperator들도 마찬가지입니다.

다른 예시를 들어드리자면

function add(x, y) { return x+y }가 있을 때

let a = 5, let b = 3

const c = add(a, b)

a = 9

을 할 때 c는 8이지 12가 아닙니다. 호출하는 순간 매개변수 값이 고정되어 버리는 거라서요.

김민서님의 프로필

김민서

질문자

2024.01.17

정말 감사합니다! 이해가 되었습니다.

calculate 클릭 이벤트가 클릭 했을때 발생하는게 아니라 코드 실행시 바로 생성되고
그때 operator는 ''로 초기화 되어있기 때문에 이런 문제가 발생한거군요

정말 감사합니다

0

콘솔로그를 어디에 넣으셨는데요? 그리고 계산 자체는 잘 돌아가나요?