하루 늦은 TIL 겸 일일 회고...!
전날 만들었던 계산기 목업에 자바스크립트를 추가해 실제 계산기처럼 동작하도록 만들었다. 앗 계산기 가능하니까 실제 계산기가 맞나
아무튼 이번에는 계산기를 구현한 코드 내용과 이해한 내용을 정리해보려고 한다.
📂 두가지 값만 가지고 연산하는 계산기
1. 첫번째 숫자 입력
if (action === "number") {
firstOperend.textContent = buttonContent;
}
클릭된 버튼이 숫자버튼이라면 첫번째 값에 입력한 버튼의 숫자값을 할당한다.
2. 두번째 숫자 입력
if (action === "number") {
// 첫번째 숫자가 0이 아니라면(입력된 값이 있다면) 버튼을 클릭했을때 두번째 칸에 버튼에 적힌 숫자를 입력
if (firstOperend.textContent !== "0") {
secondOperend.textContent = buttonContent; // 두번째 숫자 입력
} else {
firstOperend.textContent = buttonContent; // 첫번째 숫자 입력
}
}
숫자버튼이 눌러졌을때 이 수가 첫번째 수인지 두번째 수인지 판단해야 한다.
버튼이 눌러진 값이 두번째 숫자가 되어야 할 경우는 이미 첫번째 수의 값이 있을때이다.
따라서 첫번째 숫자의 값이 이미 있을때, 즉 첫번째 숫자가 초기값인 0이 아닐때 두번째 숫자에 값이 할당되도록 코드를 작성해야 한다.
3. 계산버튼 이벤트
function calculate(n1, operator, n2) {
let result = 0;
// textContent로 불러온 값이 string이기 때문에 number타입으로 바꿔줘야함
let num1 = Number(n1);
let num2 = Number(n2);
if (operator === "+") {
result = num1 + num2;
} else if (operator === "-") {
result = num1 - num2;
} else if (operator === "*") {
result = num1 * num2;
} else {
result = num1 / num2;
}
return String(result);
}
// ...
if (action === "calculate") {
calculatedResult.textContent = calculate(
firstOperend.textContent,
operator.textContent,
secondOperend.textContent
);
}
Enter 버튼이 클릭되면 숫자들과 연산자로 연산을 해야하기 때문에 calculate 함수를 작성한다.
3개의 인자를 받아서 각각 연산을 하는데, 이때 받아온 매개변수는 각 요소의 textContent 값이다.
textContent의 type은 Number가 아니라 String이기 때문에 연산을 하기 위해서 함수 내에 지역변수를 선언하고 매개변수의 type을 바꾸어 할당해주었다.
4. 초기화 버튼 이벤트
if (action === "clear") {
console.log("초기화 버튼");
firstOperend.textContent = "0";
operator.textContent = "+";
secondOperend.textContent = "0";
calculatedResult.textContent = "0";
}
초기화 버튼이 눌러지면 화면에 있는 모든 값이 처음과 같이 변해야 한다.
그러므로 버튼이 눌러졌을때 초기값이 나타나도록 값을 재할당 했다.
📂 실제 user flow와 일치하는 계산기
User Flow
사용자가 서비스나 프로그램을 어떻게 사용할지 가정하는 것.
사용자가 7000 * 6을 계산하는 상황을 가정한다.
1. 첫번째 값 입력
if (action === "number") {
if (display.textContent === "0") {
display.textContent = buttonContent;
} else {
display.textContent = display.textContent + buttonContent;
}
}
- 계산기의 화면에 나타나는 기본값은 0이다.
- 처음으로 숫자 버튼이 눌렸을때 0이 아닌 누른 버튼의 숫자 값이 나타나야 한다. (0 => 7)
- 값이 입력되었을때는 누른 버튼의 값이 계산기에 나타나 있는 숫자 뒤에 이어서 붙어야 한다. (7 => 7000)
2. 연산자 버튼 이벤트
if (action === "operator") {
operatorForAdvanced = buttonContent;
firstNum = display.textContent; // 현재 화면에 나타난 값을 저장
previousKey = "operator"; // 지금 입력된 버튼이 연산자임을 나타냄
}
- 사용자가 연산자를 눌렀을때, 눌러진 연산자의 값과 처음으로 입력된 숫자값이 저장되어야 한다.
- 변수 previousKey는 이전에 눌러진 버튼이 어떤 버튼인지 저장하고 있다.
3. 두번째 값 입력
if (action === "number") {
if (display.textContent === "0" || previousKey === "operator") {
display.textContent = buttonContent;
} else {
display.textContent = display.textContent + buttonContent;
}
previousKey = "number";
}
- 변수 previousKey의 값을 이용하여 직전 눌러진 버튼이 무엇인지 판별하는데에 사용
- 화면에 나타난 값이 0이거나(아무 숫자도 입력된 적이 없거나) previousKey가 operator라면 새로운 숫자를 입력받는다.
- 그렇지 않을 경우, 화면에 나타난 값에 새로 입력된 숫자를 붙인다.
4. 계산 버튼 이벤트
if (action === "calculate") {
previousNum = display.textContent;
display.textContent = calculate(
firstNum,
operatorForAdvanced,
previousNum
);
previousKey = "calculate";
}
처음으로 입력된 숫자, 연산자, 현재 화면에 나타난 숫자를 매개변수로 받아 calculate 함수를 실행하고, 결과값을 화면에 나타낸다.
5. 초기화 버튼 이벤트
if (action === "clear") {
firstNum = undefined;
operatorForAdvanced = undefined;
previousNum = undefined;
display.textContent = "0";
previousKey = "clear";
}
계산작업을 수행할때 사용되었던 모든 변수들의 내용을 초기화한다.
6. 소수점 버튼 이벤트
if (action === "decimal") {
// 1. .이 입력되면 숫자 뒤에 .을 추가한다
// 2. 만약 디스플레이에 이미 .이 추가되어있다면 .을 추가하지 않는다(.이 1개만 들어가게)
// 3. 정수 부분 없이 .과 숫자를 눌러서 작동하는 경우 0.이 붙은 소수가 되어야 한다.
// => 마지막으로 누른 버튼이 연산자이고 소숫점 버튼이 클릭되었다면 두번째 숫자의 값의 시작을 0.으로 만든다
if (
!display.textContent.includes(".") &&
previousKey !== "operator"
// .이 없음 + 이전 키가 연산자가 아니다(숫자) = 소숫점만 추가해주면 됨
) {
display.textContent = display.textContent + ".";
} else if (previousKey === "operator") {
// 연산자 다음에 소수점 클릭 = 정수가 될 숫자가 없음! = 0으로 시작해야 함
display.textContent = "0.";
}
previousKey = "decimal";
}
- 소수점 버튼이 클릭되면 숫자 뒤에 .을 추가한다.
=> display.textContent = display.textContent + ".";
- 만약, 디스플레이에 이미 소수점이 추가되어있다면 .을 추가하지 않는다(소수점은 하나만 나타나야한다).
=> if (!display.textContent.includes("."))
디스플레이의 textContent에 .이 포함되어있다가 거짓이라면 = .이 포함되어 있지않을 경우가 true
- 정수 부분 없이 .과 숫자를 눌러서 계산기가 작동할 경우, 해당 숫자는 0.이 붙은 소수가 되어야 한다. 즉 .7이 입력된 경우 0.7로 나타나야 한다.
=> previousKey === "operator"
직전에 누른 키가 연산자라면 = 연산자 다음 .이 눌러졌다면 = 정수가 될 숫자가 없으므로 정수부분에 0이 추가되어야함
7. 계산 버튼 이벤트 2
if (action === "calculate") {
// 1. 디스플레이에 숫자1(연산자)숫자2 한 결과가 나타나야한다 => 함수호출
// 2. 연산자가 저장되어있으면서 엔터가 눌러졌을때만 게산이 실행되게 한다
// 3. 엔터가 여러번 눌러졌을때 이전 숫자에 저장된 연산자로 반복된 계산이 수행되어야 한다.
// 엔터가 여러번 눌러졌다 = 현재 previousKey가 calculate이다 (엔터 입력 1번 이상)
if (operatorForAdvanced) {
if (previousKey === "calculate") {
// 2번 이상으로 엔터가 눌릴때
// 현재 디스플레이에 있는 숫자에 이전 숫자와 연산자가 계산됨
firstNum = display.textContent;
display.textContent = calculate(
firstNum,
operatorForAdvanced,
previousNum // 처음 엔터가 눌릴때 화면에 있었던 두번째 값
);
console.log(previousNum);
} else {
// 처음으로 엔터가 눌릴때
previousNum = display.textContent;
display.textContent = calculate(
firstNum,
operatorForAdvanced,
previousNum
);
}
previousKey = "calculate";
console.log(previousKey);
}
}
- Enter가 입력되면 숫자1(연산자)숫자2를 계산한 결과가 화면에 나타나야 한다.
- 연산자가 저장되어 있으면서 엔터가 눌러졌을때만 계산이 실행되어야 한다. (숫자만 누르고 엔터를 눌렀을때는 계산되지 않도록)
=> if (operatorForAdvanced)
= operatorForAdvanced가 true일 경우 = 변수에 값이 있을경우 = 연산자가 저장되었을 경우
- 엔터가 여러번 눌러졌을경우, 이전 숫자와 저장된 연산자로 반복된 계산이 수행되어야 한다.
************
내용도 많고 이해가 늦게 된 부분도 있어서 정리와 회고가 조금 많이 늦어졌다
직접 디자인한 계산기에 동작하는 스크립트를 입혀서 테스트 해보니까 엄청 뿌듯했음!
페어와 함께 어느정도 해결하긴 했지만 난이도가 있는 부분은 생각이 많이 필요했는데, 나중에 코드 설명을 듣고 혼자서 처음부터 연습해본게 이해하는데 많은 도움이 되었다. 역시 코드는 직접 연습을 해봐야 많이 느나봐
또 직접 구현하면서 if문의 조건을 어떻게 설정해야 하는지 많은 공부가 되었다.
부정연산자를 사용한다거나, truty 또는 falsy한 값을 사용해서 조건을 설정하는 부분에 대해 더 알수있었던거같다.
아무튼 구현한 css랑 js파일 정리해서 깃허브에 올려뒀다!
나중에 좀 더 좋은 코드가 생각나거나 시간이 좀 더 지나서 지금보다 실력이 늘면 더 간단한 방법으로 구현할 수 있겠지
그때까지 열심히 하자 아무튼,,
이제 오늘거 정리해서 회고해야함 ㅎ 이것도 아마 내일하지 싶다...
아무튼22 이 이상은 미루지말고 운동도 하고.. 할수있는만큼 바짝바짝 땡겨서 하자
'study > TIL' 카테고리의 다른 글
22.12.30 - 객체 (0) | 2022.12.30 |
---|---|
22.12.29 - 배열 (0) | 2022.12.29 |
22.12.26 - 계산기 목업, flex (0) | 2022.12.26 |
22.12.23 - 레이아웃, display: flex (0) | 2022.12.23 |
22.12.22 - CSS 개요, 박스모델, CSS 선택자 (0) | 2022.12.22 |