일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- JS
- github
- jQuery
- 실기
- 코드공유
- 프론트엔드
- 웹퍼블리셔
- 슬라이드전환
- 코딩독학
- CSS
- 타입스크립트
- 웹디자인기능사실기
- 렛츠기릿자바스크립트
- 세로메뉴바
- web
- git
- PROJECT
- react
- 웹디자인기능사
- 정보처리기사
- 웹디실기
- 리액트
- JavaScript
- HTML
- Supabase
- 연산자
- 자바스크립트
- 생활코딩
- 비전공자
- 깃
- Today
- Total
코딩하는라민
렛츠기릿 자바스크립트 #6 계산기 만들기 - 함수 사용하기 본문
렛츠기릿 자바스크립트 #6 계산기 만들기 - 함수 사용하기
책 + 저자 유튜브 강의(인프런) + 추가로 모르는 내용들 필기 추가하면서 공부
1. 순서도 그리기
① 숫자1, 2 / 연산자 를 저장할 변수를 각각 생성
② 숫자를 누르면 연산자가 입력된 유무에 따라서 숫자1에 저장할지, 숫자2에 저장할지 결정하고 변수에 숫자 저장
③ 연산자 버튼을 누르면 숫자1의 유무에 따라 연산자를 저장하거나 경고창을 띄운다
④ = 버튼을 누르면 숫자2의 유무에 따라 연산자를 결과에 출력하거나 경고창을 띄운다
기본원리
- 숫자1이 존재해야 연산자가 존재 가능하고, 연산자가 존재해야 숫자2가 존재 가능하다.
2. 변수 생성하고 버튼에 이벤트리스너 달기
① 변수 생성
let numOne='';
let numTwo='';
let operator='';
- 비어있는 변수 생성
② 버튼에 이벤트리스너 달기
document.querySelector('#num-0').addEventListener('click', ()=>{})
document.querySelector('#num-1').addEventListener('click', ()=>{})
document.querySelector('#num-2').addEventListener('click', ()=>{})
document.querySelector('#num-3').addEventListener('click', ()=>{})
document.querySelector('#num-4').addEventListener('click', ()=>{})
document.querySelector('#num-5').addEventListener('click', ()=>{})
document.querySelector('#num-6').addEventListener('click', ()=>{})
document.querySelector('#num-7').addEventListener('click', ()=>{})
document.querySelector('#num-8').addEventListener('click', ()=>{})
document.querySelector('#num-9').addEventListener('click', ()=>{})
document.querySelector('#plus').addEventListener('click', ()=>{})
document.querySelector('#minus').addEventListener('click', ()=>{})
document.querySelector('#divide').addEventListener('click', ()=>{})
document.querySelector('#multiply').addEventListener('click', ()=>{})
- 각 버튼을 눌렀을 때 함수가 실행되도록 이벤트리스너르 ㄹ달아준다.
③ 고차함수
- 함수는 호출하면 숫자, 문자열, 불값 등을 변환한다.
고차함수 (Higher order function)
: 함수를 파라미터로 전달받거나, 함수를 연산의 결과로 반환해주는 메서드
const func = () => {
return () => {
console.log('hello ramin!');
}
} // func 를 호출하면 안에 있는 함수를 리턴한다.
내장고차함수(배열에 한함)
- .filter : 배열의 요소 중에서 특정 조건을 만족하는 요소들만을 걸러내는(filter) 메서드
- .map : 배열의 요소를 일괄적으로 변경하는데 효과적
- .reduce : 호출하는 배열의 각각의 멤버에 대해서 콜백 함수를 실행하고 하나의 결과 값만 내보냄
3. 버튼을 눌렀을 때 실행할 함수 지정해주기
① 숫자 버튼
const $operator = document.querySelector('#operator');
const $result = document.querySelector('#result');
const onClickNumber = (number) => () => {
if(operator){
if(!numTwo){
$result.value='';
}
numTwo += event.target.textContent;
} else{
numOne += event.target.textContent;
}
$result.value += event.target.textContent;
}
document.querySelector('#num-0').addEventListener('click', onClickNumber)
document.querySelector('#num-1').addEventListener('click', onClickNumber)
...
- 연산자가 있으면 숫자2에 누른 버튼의 숫자를 더하고, 연산자가 없으면 숫자1에 버튼의 숫자를 더한다.
- 그리고 그 결과를 화면에 띄운다.
- 각 이벤트 리스너 연결하여 버튼을 눌러을 때 해당 함수가 실행되도록 해준다.
if(!numTwo){
$result.value='';
}
- operator 가 있는 상태에서 / 숫자키를 누르면 / 숫자2가 없을 때 결과창을 비워줘야 숫자2가 숫자1 옆에 붙지 않고 연산을 제대로 진행할 수 있다.
const onClickNumber = (event) => {
if(!operator){
numOne += event.target.textContent;
$result.value += event.target.textContent;
return;
}
// 아래부터는 operator 가 있는 경우
if(!numTwo){
$result.value='';
}
numTwo += event.target.textContent;
$result.value += event.target.textContent;
}
- if문의 중복 제거 : if문 다음에 나오는 공통부분을 안쪽에 각각 넣기 > 짧은 문장을 맨 위로 올려준다 > else 제거 > 반복
- 맨 위에 있는 절차의 끝에는 return을 넣어준다.
② 연산자 부분
const onClickOperator = (op) => () => {
if(numOne){
operator = op;
$operator.value = op;
} else{
alert('숫자가 없습니다. 숫자 먼저 입력해주세요.');
}
}
document.querySelector('#plus').addEventListener('click', onClickOperator('+'));
document.querySelector('#minus').addEventListener('click', onClickOperator('-'));
document.querySelector('#divide').addEventListener('click', onClickOperator('/'));
document.querySelector('#multiply').addEventListener('click', onClickOperator('*'));
- 함수 부분은 고차함수로 하지 않으면 버튼을 클릭했을 때 함수가 제대로 실행되지 않는다.
- 연산자를 눌렀을 때 숫자1이 있다면 연산자가 화면에 표시되고, 숫자1이 없다면 경고창을 띄운다.
③ 계산하기 버튼
document.querySelector('#calculate').addEventListener('click', ()=>{
if(numTwo){
switch (operator) {
case '+':
$result.value = parseInt(numOne) + parseInt(numTwo);
break;
case '-':
$result.value = numOne - numTwo;
break;
case '/':
$result.value = numOne / numTwo;
break;
case '*':
$result.value = numOne * numTwo;
break;
}
} else {
alert('잘못된 연산입니다.');
}
});
- 계산하기 버튼을 눌렀을 때 숫자2가 있다면 누른 연산자에 해당하는 연산 결과가 실행되고, 숫자2가 없으면 경고창을 띄운다.
- parseInt () : +는 문자열을 연결해주는 역할이다.
→ 예를들면 12+34 는 46이 아니라 1234이다.
→ 따라서 parseInt는 문자열을 숫자로 바꿔준다.
→ + 를 제외한 연산자는 문자열을 숫자로 바꿔주고 나서 연산을 실행한다.
→ 즉, + 연산을 할 경우에는 parseInt 를 써준다.
④ 리셋 버튼
document.querySelector('#reset').addEventListener('click', ()=>{
numOne='';
numTwo='';
operator='';
$operator.value='';
$result.value='';
});
- 리셋 버튼을 누르면 변수를 초기화하고, input 에 띄워진 값도 처음으로 되돌려준다.
4. 연산 가능 개수 늘리기 → 혼자 생각해보기
- 계산기는 2자리의 연산만 하는 것이 아니라 여러 가지 숫자의 사칙연산을 할 수 있어야 한다.
- 따라서 계산기가 작동하는 원리를 생각해보는 시간이 되었다.
[ 정답 ]
...
const onClickOperator = (op) => () => {
...
if(numTwo){
switch (operator) {
case '+':
$result.value = parseInt(numOne) + parseInt(numTwo);
break;
case '-':
$result.value = numOne - numTwo;
break;
case '/':
$result.value = numOne / numTwo;
break;
case '*':
$result.value = numOne * numTwo;
break;
}
numOne = $result.value;
numTwo ='';
}
}
...
- 연산자 버튼을 눌렀는데 숫자2가 있는 상태이면,
- numOne 에 $result.value 값을 대입 : 숫자1은 결과값이 되고, 숫자2는 초기화된다.
- 예를 들어서 1+2+3을 계산한다고 하면, 1+2를 계산해 3이 되고, 그 다음에 3과 3을 더해 6이라는 결과가 나오는 원리이다. 따라서, 1+2 를 숫자1에 저장하고, 3을 숫자2에 저장해 숫자1 + 숫자2 의 결괏값을 만드는 것.
parseInt
: 문자열 인자를 파싱하여 특정 진수의 정수를 반환
Number.parseInt(string)
- string : 파싱할 값. 문자열이 아닐 경우에는 toString 연산을 통해 문자열로 변경
Number.parseInt(string, radix)
- radix : 진수를 나타내는 2부터 36까지의 정수.
문자를 숫자로 변환할 수 없는 경우나, 진수를 잘못 입력한 경우는 NaN 값이 나온다.
eval()
eval 함수를 이용하면 parseInt 함수를 쓰지 않아도 된다.
하지만 이 함수를 이용하면 해커가 입력한 코드를 사용할 수 있기 때문에 ** 보안상 이유로 eval 은 쓰지 않는다.
5. +나 -로 시작하는 숫자의 연산 → 혼자 생각해보기
const onClickOperator = (op) => () => {
if(numTwo){
switch (operator) {
case '+':
$result.value = parseInt(numOne) + parseInt(numTwo);
break;
case '-':
$result.value = numOne - numTwo;
break;
case '/':
$result.value = numOne / numTwo;
break;
case '*':
$result.value = numOne * numTwo;
break;
}
numOne = $result.value;
numTwo ='';
}
if(numOne){
operator = op;
$operator.value = op;
} else if(operator==='-'||'+'){
operator = op;
$operator.value = op;
} else{
alert('숫자가 없습니다. 숫자 먼저 입력해주세요.');
}
}
- if문 안에 else if 문을 추가해준다.
- else if 문의 조건문에는 연산자가 - 또는 + 으로 해준다.
▶ 논리연산자
① ||
- or (엔터 위, 원표시 위에 문자)
- 둘 중 하나만 참(true)이어도 참(true)
② &&
- and
- 둘 다 참(true)이어야 참(true)
- 하나만 참(true)이거나 둘 다 거짓(false)이면 거짓(false)
① 오류_함수의 순서
- 그런데 else if문을 추가해준 if(numOne) 의 순서가 앞에서 추가해준 if(numTwo) 보다 아래에 있어야 정상적으로 작동된다.
- 아래의 코드와 같이 순서가 된다면, 연산자를 누르고 숫자를 누르면 NaN 이라고 결과창에 뜨면서 연산을 마친 후 계산하기 버튼을 눌러도 NaN 이라는 결과가 뜬다.
const onClickOperator = (op) => () => {
if(numOne){
operator = op;
$operator.value = op;
} else if(operator==='-'||'+'){
operator = op;
$operator.value = op;
} else{
alert('숫자 먼저 입력해주세요!!');
}
if(numTwo){
switch (operator) {
case '+':
$result.value = parseInt(numOne) + parseInt(numTwo);
break;
case '-':
$result.value = numOne - numTwo;
break;
case '/':
$result.value = numOne / numTwo;
break;
case '*':
$result.value = numOne * numTwo;
break;
}
numOne = $result.value;
numTwo ='';
}
}
'Core > JavaScript' 카테고리의 다른 글
[JavaScript] 클래스(Class)와 constructor (0) | 2023.02.20 |
---|---|
[Javascript] 참조 범위를 결정짓는 스코프(scope) - 1 (0) | 2022.11.24 |
렛츠기릿 자바스크립트 #5 끝말잇기 게임 만들기 (0) | 2022.10.27 |
렛츠기릿 자바스크립트 책 #4 함수, 객체 (7) | 2022.10.22 |
렛츠기릿 자바스크립트 책 #3 객체, 배열 (0) | 2022.10.21 |