[BCGD] 비전공자 백엔드 개발 도전기 (주말과제)

2025. 3. 31. 01:21·JavaScript
728x90

☑️ 계산기 만들기

 

✅ DOMContentLoaded 이벤트 리스너 등록

 

웹 페이지가 완전히 로드되었을 때 실행될 함수를 등록

DOMContentLoaded 이벤트는 HTML이 로드 및 파싱된 후 실행

document.addEventListener("DOMContentLoaded", function () {

 

 

 

✅ 변수설정

 

result : 계산 결과 출력

buttons : 모든 버튼 요소저장

expression : 사용자가 입력한 계산식(수식)을 저장할 변수를 선언하고 초기화

let result = document.getElementById("result");
let buttons = document.querySelectorAll("#calculator input[type='button']");
let expression = "";

 

 

 

✅ 버튼 클릭 이벤트 리스너 추가

 

모든 버튼(buttons)에 대해 forEach 반복문을 사용하여 클릭 이벤트 리스너를 추가

각 버튼이 클릭될 때 실행되는 익명 함수를 정의

 

let value : 클릭된 버튼의 값을 가져와 value 변수에 저장

buttons.forEach(button => {
    button.addEventListener("click", function () {
		let value = this.value;

 

 

✅ =(등호) 버튼이 클릭된 경우

 

마지막 입력이 연산자(+, -, *, /, %)인 경우: 연산자를 제거한 식을 다시 추가하여 연산자가 연속으로 오는 것을 방지

ex) 3-3- = 0

 

eval() :  결과값을 expression에 저장하여 계속 계산(문자열 → 수식화)

* eval()은 보안상 위험할 수 있으므로, 실제 프로젝트에서는 대체 방법을 고려

 

예외처리 : Error 처리 + 계산 입력수식 "" (초기화)

if (value === "=") {
    try {
        if (expression.slice(-1).match(/[\+\-\*/%]/)) {
            expression = expression.slice(0, -1); // 마지막 연산자를 제외한 값 추가
        }
        result.value = eval(expression); // 계산 실행
        expression = result.value; // 결과 유지
    } catch (e) {
        result.value = "Error";
        expression = "";
    }
}

 

 

✅ AC(초기화) 버튼 처리

 

expression을 비우고, result를 "0"으로 초기화

else if (value === "AC") {
  expression = "";
  result.value = "0";
}

 

 

✅ 연산자로 시작하는 것을 방지

 

처음 입력이 빈칸,  +, -, *, /, % 같은 연산자인 경우 입력을 무시

} else {
    if (expression === "" && value.match(/[\+\-\*/%]/)) {
        return;

 

 

✅ 연산자 연속 입력 방지

 

slice(-1).match(/[\+\-\*/%]/) : 마지막 저장된 수식

value.match(/[\+\-\*/%]/) : 지금 입력된 수식

ex) 3+4--4 일 경우

} else if (
    expression.slice(-1).match(/[\+\-\*/%]/) && value.match(/[\+\-\*/%]/)

 

 

✅ (, )의 잘못된 조합 방지

 

'(' 다음으로 */%<>= 수식이 나올경우 + ')' 다음으로 *0~9 수식이 나올경우

|| expression.slice(-1) === "(" && value.match(/[\*/%,<>=]/) 
|| expression.slice(-1) === ")" && value.match(/[0-9]/)

 

 

✅ 0으로 시작하는 숫자 입력 방지

 

1. (^|[\+\-\*/%]) → "0" 앞의 문자 검사

^ : 문자열의 시작을 의미

| : 또는(OR) 연산자 (좌우 둘 중 하나가 해당되면 매칭됨)

[\+\-\*/%] : +, -, *, /, % 중 하나와 매칭됨

대괄호 [] 안의 특수문자는 백슬래시 \를 붙여야 함 (예: \+, \*, \%)

 

즉, "0" 앞에 있는 문자가 아래 중 하나라면 매칭됨:

- 문자열의 시작 (^)

- 연산자 (+, -, *, /, %)

 

2. 0$ → "0"이 마지막 문자

0 : 숫자 0과 매칭

$ : 문자열의 끝을 의미

 

현재 입력한 계산식 상태에서 0 앞이 숫자가 아니고, 지금 입력받은 수식이 순자이면 → 0 생략

ex) (1+2) +(0 앞에 숫자가 아니고) 0 3(0 뒤에 숫자일 경우 0 삭제) 

if (expression.match(/(^|[\+\-\*/%])0$/) && value.match(/[0-9]/)) {
    expression = expression.slice(0, -1); // 마지막 "0" 제거
}

 

 

✅ 입력값 추가 및 결과 출력

사용자가 입력한 값을 expression에 추가하고 화면(result.value)에 출력

expression += value;
result.value = expression;

 

☑️ 전체코드

document.addEventListener("DOMContentLoaded", function () {
    let result = document.getElementById("result");
    let buttons = document.querySelectorAll("#calculator input[type='button']");
    let expression = "";
        
    buttons.forEach(button => {
        button.addEventListener("click", function () {
            let value = this.value;
        
            if (value === "=") {
                try {
                    if (expression.slice(-1).match(/[\+\-\*/%]/)) {
                        expression = expression.slice(0, -1); // 마지막 연산자를 제외한 값 추가
                    }
                    result.value = eval(expression); // 계산 실행
                    expression = result.value; // 결과 유지
                } catch (e) {
                    result.value = "Error";
                    expression = "";
                }
            } else if (value === "AC") {
                expression = "";
                result.value = "0";
            } else {
                if (expression === "" && value.match(/[\+\-\*/%]/)) {
                    return; // 연산자로 시작 방지
                } else if (
                    expression.slice(-1).match(/[\+\-\*/%]/) && value.match(/[\+\-\*/%]/) // 연산자 연속 입력 방지
                    || expression.slice(-1) === "(" && value.match(/[\*/%,<>=]/) // ( 뒤에는 -, 숫자 가능 (음수 허용)
                    || expression.slice(-1) === ")" && value.match(/[0-9]/) // ) 뒤에는 숫자가 바로 올 수 없음
                ) {
                    return; // 잘못된 입력 방지
                }
            
                // 앞이 "0"이고, 뒤에 숫자가 오는 경우 "0"을 제거
                if (expression.match(/(^|[\+\-\*/%])0$/) && value.match(/[0-9]/)) {
                    expression = expression.slice(0, -1); // 마지막 "0" 제거
                }
            
                // 결과 출력
                expression += value;
                result.value = expression;
            }
        });
    });
});

 

PS. 생각했던 것 보다 더 많은 변수/예외 상황을 고려하여 코드를 작성 해야하는 작업을 통해 공통범위를 잘 묶어서 처리하고, 오류상황에 대해 생각하는 스펙트럼이 넓어진 것 같다. 여기에서 더 많은 옵션과 변수처리를 할수있을 것 같다. 

728x90

'JavaScript' 카테고리의 다른 글

[BCGD] 비전공자 백엔드 개발 도전기 (개인프로젝트)  (0) 2025.03.31
[BCGD] 비전공자 백엔드 개발 도전기 (37)  (1) 2025.03.29
[BCGD] 비전공자 백엔드 개발 도전기 (36)  (0) 2025.03.28
[BCGD] 비전공자 백엔드 개발 도전기 (35)  (2) 2025.03.25
[JavaScript] forEach/each/append/appendChild 총 정리  (0) 2025.03.23
'JavaScript' 카테고리의 다른 글
  • [BCGD] 비전공자 백엔드 개발 도전기 (개인프로젝트)
  • [BCGD] 비전공자 백엔드 개발 도전기 (37)
  • [BCGD] 비전공자 백엔드 개발 도전기 (36)
  • [BCGD] 비전공자 백엔드 개발 도전기 (35)
PUSH → MERGE → DEPLOY
PUSH → MERGE → DEPLOY
데이터 흐름과 운영 자동화를 설계하는 백엔드 개발자
  • PUSH → MERGE → DEPLOY
    Coding Dongin
    PUSH → MERGE → DEPLOY
  • 전체
    오늘
    어제
    • MEUN N
      • 코테(Solved.ac + Programmers) N
      • BootCamp(JAVA)
      • JAVA
      • SpringBoot
      • JavaScript
      • JSP
      • DB(SQL)
      • React
      • HTML_CSS
      • jQuery
      • SCSS
      • GSAP
      • 설치 + 꿀팁
      • 정보처리기사 오답노트
      • 정보처리기사 기출문제
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GIT
  • 공지사항

  • 인기 글

  • 태그

    백준
    실기
    정처기오답노트
    dp
    solved.ac
    프로그래머스
    완전탐색
    level0
    백엔드개발자
    코딩테스트
    정렬
    브루트포스
    자료구조
    정처기
    문자열
    level1
    피보나치
    정보처리기사
    정처기실기
    자바
    Level2
    기출문제
    springboot
    수학
    시뮬레이션
    정보처리기사 실기 기출문제
    배열
    알고리즘
    구현
    java
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.4
PUSH → MERGE → DEPLOY
[BCGD] 비전공자 백엔드 개발 도전기 (주말과제)
상단으로

티스토리툴바