TIL

0l0l·2021년 6월 3일
0

TIL

목록 보기
45/86

계산하기 (함수 학습)

➕ readonly 속성
: input창에 키보드로 입력할 수 없고, 읽기만 가능하도록 설정(자바스크립트를 이용한 입력은 가능)

➕ 단축키★
Alt + Shift + ⇅ : 코드 복사/붙여넣기

자바스크립트에서 태그를 변수에 저장할 때, 태그명 앞에 $를 붙여 변수이름을 '$태그명' 이라 설정(강사님만의 규칙)

1. 함수 중복 제거하기(고차함수)

중복된 코드를 작성하고 있다면 잘못 작성하고 있는 것!
중복을 제거해 코드를 줄이도록 다시 생각해봐야 한다!

✨ Tip! 함수에서 중복을 제거하려면 중복되는 코드 안에서 '달라지는 특정 부분'을 매개변수로 만든다.
매개변수로 만들어줌으로써 중복(함수)인 전체 코드를 변수에 저장해준다. (함수가 필요할 때마다 변수를 사용!)

※ 자바스크립트 변수에만 데이터를 바꾸는 것이 아니라 동시에 💻화면에 표시되는 데이터도 바꿔줘야 한다!

고차함수(high order function): 함수가 함수를 리턴(호출)하는 함수

(맨 마지막 3번째 흐름 코드 참고)

// 1️⃣번째 흐름

const onClickNumber = (number) => {
  if (operator) { // 연산자 변수 들어있는 경우
    numTwo += number;
  } else { // 연산자 변수 비어있는 경우
    numOne += number;
  }
  $result.value += number; // 화면에 값 표시
  // return undefined;
};

document.querySelector('#num-0').addEventListener('click', onClickNumber('0'));

📌 코드 흐름 파악하기!
addEventListener 메서드의 두번째 인자인 '함수 자리'에 함수가 아닌 undefined를 return하지 않도록, (버튼을 click해도 아무것도 실행되지 않는다!😱)
return 함수 안에 실제로 동작하는 코드를 넣음으로써 함수가 실행되고 함수 실행값이 return 되도록 한다. (즉, 고차함수를 사용한다.)

// 2️⃣번째 흐름
// 함수 실행된 값을 리턴하기 위해 return 안에 함수를 넣음

const onClickNumber = (number) => {
  /* 🔽 return 안으로 이동!!
  if (operator) {
    numTwo += number;
  } else {
    numOne += number;
  }
  $result.value += number;
  */
  return = () => {
    if (operator) {
      numTwo += number;
    } else {
      numOne += number;
    }
    $result.value += number;
  };
};
// 3️⃣번째 흐름
// 화살표 함수는 중괄호와 return 예약어 생략 가능
// '(number) => () =>'와 같이 화살표가 연달아 나오는 형태를 취함 
// ↳'함수 안에 함수가 있다', '함수가 함수를 리턴한다'로 해석 (∴고차함수)
// ↳매개변수에 number를 넣고 함수 실행 => return 함수를 실행해 앞의 함수 실행값을 리턴

const onClickNumber = (number) => () => {
  if(operator) {
    numTwo += number;
  } else {
    numOne += number;
  }
  $result.value += number;
};

2. event 객체로 중복 제거하기

원래 빈 괄호 모양이었던 자리에는 브라우저가 제공하는 event 매개변수가 존재한다.
아래의 코드처럼 고차함수 형태로 작성함으로써 addEventListenter 함수에 들어가고 중복도 제거할 수 있다.

// 중괄호({)와 return을 생략한 형태의 고차함수
const onClickNumber = (number) => (event) => {
  ...
};

🎊event 객체 간단 예시
click 이벤트가 발생하면 eventClick 함수가 실행되는데, 사실 브라우저가 eventClick 함수를 몰래 호출한다.
브라우저가 event 객체를 만들어 그 객체는 인수로 넣어지고 함수의 매개변수로 전달되어 함수가 실행된다.

const eventClick = (event) => { 
  console.log(event.target.value);
};

document.querySelector('.#input').addEventListener('click', eventClick);

// eventClick(event);

고차함수(high order function)

함수를 만들어내는 함수이며, 함수 간의 중복을 제거할 수 있다.
(실무에서도 중괄호, return 생략된 코드를 많이 사용)

<매개변수가 없는 고차함수>

// 아래 코드와 동일함
const func = () => {
  return () => {
    console.log('hello');
  };
};

// 함수의 리턴값을 변수에 넣어주는 형태
// 함수를 호출하는 부분이 이해가지 않는다면 return값으로 대체❗(위 코드 참고)
const innerFunc = func();
innerFunc(); // hello

<매개변수가 있는 고차함수>
고차 함수에서 중괄호({)와 return 예약어 생략 가능하다.
(화살표가 연달아 나타나는 형태 보고 당황하지 않기!🤨)

// 빈 괄호부터는 return하는 부분으로 이해
const func = (msg) => () => {
  console.log(msg);
};

// 위와 같은 코드
const func = (msg) => {
  return () => {
    console.log(msg);
  };
};
// func 함수 호출하면 console.log(매개변수)되는 함수가 반환
const innerFunc1 = func('hello');
const innerFunc2 = func('javascript');
const innerFunc3 = func();
innerFunc1; // hello
innerFunc2; // javascript
innerFunc3; // undefined: 빈 값의 경우

/* ----- 대체 코드(중괄호 return 생략) ----- */
const innerFunc1 = () => {
  console.log('hello');
};

const innerFunc2 = () => {
  console.log('javascript');
};

const innerFunc3 = () => {
  console.log();
};

➕ 단축키 마우스 휠 클릭 + 드래그 : 원하는 부분 드래그하여 줄마다 커서 위치하도록 함. (원하는 부분 한번에 선택해 삭제 가능)

✨ 추가 Tip! (실력차를 나타내는 잔재주🤓)
(태그의 값을 나타내는 속성으로 textContent를 사용하는 일반 태그의 경우) event.target.textContent를 사용해 고차함수 사용하지 않고 중복 코드를 줄일 수 있다.

3. if문 중첩 줄이기

계산기에서 피연산자 두 개의 숫자가 연속으로 표시되지 않도록 만들기
=> 두번째 숫자를 클릭하기 전에, 이전에 클릭했던 첫번째 숫자를 화면에서 지워 빈 화면으로 만들기

const onClickNumber = (event) => {
  if (operator) {
    if (!numTwo) { // 두번째 숫자를 클릭하고 변수에 저장되기 직전에
      $result.value = ''; // 빈 화면으로 표시
    }
    ...
  };
};

if문 안에 if문이 들어가는 중첩 형태는 최대한 줄여 코드를 보기 쉽게 작성하는 것이 좋다.

<중첩 if문 제거하는 방법>

  1. if문 다음에 나오는 공통된 절차를 각 분기점 내부에 넣는다.

  2. 분기점에서 짧은 절차부터 실행하도록 if문을 작성한다.
    (✳ 내가 이해하기 위한 추가 설명: 기존에 작성한 if문이 반대 형태(if-긴 절차, else-짧은 절차)인 경우, 작은 if-else를 감싸는 if 조건문에 !를 넣어 반대로 실행되도록 만든다.)

  3. 짧은 절차가 끝나면 return(함수 내부의 경우)이나 break(for문 내부의 경우)로 중단한다.

  4. else를 제거한다(이때 중첩 하나가 제거된다).
    (✳ 내가 이해하기 위한 추가 설명: return은 코드를 종료하므로 뒤에 있는 else가 필요 없다. 없어짐으로써 중첩 if문 → 2개의 if문 형태로 바뀜)

  5. 다음 중첩된 분기점이 나오면 1~4의 과정을 반복한다.

4. 결과 계산하기, 초기화

결과 계산하기

연산자에 따라 다르게 실행되는 코드 각각 작성하기

더하기(+)는 숫자도 문자열로 판단해 parseInt를 사용해야 한다.
이와 달리 빼기(-), 곱하기( * ), 나누기(/)는 자동으로 문자열을 숫자로 (또는 숫자를 문자열로) 바꿔주기 때문에 parseInt를 사용하지 않아도 된다.

if (numTwo) {
  switch (operator) {
    case '+':
      $result.value = parseInt(numOne) + parseInt(numTwo);
      break;
    case '-':
      $result.value = parseInt(numOne) - parseInt(numTwo);
      break;
    case '*':
      $result.value = parseInt(numOne) * parseInt(numTwo);
      break;
    case '/':
      $result.value = parseInt(numOne) / parseInt(numTwo);
      break;
    default:
      break;
  }
}

📒숙제~ switch/case문 → if문으로 바꿔보기! (switch/case ⇄ if 연습!)

if (numTwo) {
  if (operator === '+') {
    $result.value = parseInt(numOne) + parseInt(numTwo);
  } else if (operator === '-') {
    $result.value = numOne - numTwo;
  } else if (operator === '*') {
    $result.value = numOne * numTwo;
  } else if (operator === '/') {
    $result.value = numOne / numTwo;
  }
} else {
  alert('숫자를 먼저 입력하세요');
}

// 중첩 if문 줄이기
if (!numTwo) {
  alert('숫자를 먼저 입력하세요');
}
if (operator === '+') {
  $result.value = parseInt(numOne) + parseInt(numTwo);
}
/* 이어서 -, *, / 조건문 */

초기화하기

계산작업을 reset하는 것이기 때문에 코드에서 초기상태(ex. 변수선언)를 맨 위에 몰아 작성하는 것이 좋다.
초기화하는 버튼을 클릭하여 이벤트가 발생하면 피연산자와 연산자 변수를 초기화하고, 값이 표시되는 화면을 빈 화면으로 만든다.

let numOne = '';
let operator = '';
let numTwo = '';
const $operator = document.querySelector('#operator');
const $result = document.querySelector('#result');

/* ...(실행코드 생략) */

// 🔽초기화 코드
document.querySelector('#clear').addEventListener('click', () => {
  numOne = '';
  operator = '';
  numTwo = '';
  $operator.value = ''; // 클릭한 연산자가 표시되는 화면
  $result.value = ''; // 계산 결괏값이 표시되는 화면
});

➕ 단축키 Alt + ⇅ : (커서가 위치한)선택한 코드 위아래로 이동하여 줄바꾸기


연달아 계산하기 (계산하기 심화)

알고리즘이 바뀌면 먼저 '순서도'를 수정해 그려보고, 코드에 옮겨 작성하기❗ (머릿속으로만 생각하고 바로 코드 수정하는 습관❌)
고차함수를 이용해 return으로 함수를 반환한다....🤔

Hint : 1 + 2+ 3은 실제로 계산기에 1, +, 2, =, +, 4, = 순으로 버튼을 눌러야 한다. 두번째 '+'를 눌렀을 때 numOne, operator, numTwo 변수가 가지고 있어야 할 값이 무엇일까?
=> 첫번째 '='버튼을 클릭할 때 계산 결과를 numOne 변수에 저장하고, operator와 numTwo 변수를 비워 이어서 클릭하는 연산자와 숫자값을 저장한다.

if (operator) {
  /* ...(연산자에 따라 실행되는 코드 생략) */
  
  $operator.value = ''; // 연산자 아무것도 없이 빈 화면
  numOne = $result.value; // 첫번째 숫자 변수에 이전 계산 결괏값 저장
  operator = ''; // 연산자 변수 비워두기
  numTwo = ''; // 두번째 숫자 변수 비워두기
} else {
  alert('숫자부터 입력하세요');
}

📒숙제~ 첫번째 숫자에 음수인 '-'먼저 입력이 가능하도록 작성해보기!
📒숙제~ 중간마다 '='클릭하지 않고 이어서 계산하기 위해 연산자를 클릭했을 때 결과값이 나오도록 구현해보기!

profile
천방지축 빙글빙글

0개의 댓글