초보자도 따라 하는 사칙연산 자바스크립트 계산기 구현 가이드

지난 번 할 일 목록(To do List) 만들기에는 LocalStorage을 활용하는 방법에 대해서 글을 작성했는데요. 오늘은 간단한 사칙 연산이 포함된 계산기를 만들어볼까 합니다. 단순하고 간단해 보이지만 실제로 구현하면 신경 써야 될 부분이 더러 있습니다.

숫자 버튼을 누르면 화면에 숫자가 나오고, 연산자를 누르면 계산이 된다. 단순해 보이는 이 흐름 뒤에는 생각보다 꼼꼼한 설계가 필요했습니다. 자바스크립트 계산기의 코드를 처음 짰을 때, 숫자를 누르기도 전에 연산자가 찍히거나 ‘0’이 무한정 늘어나는 것을 보고 당황했던 기억이 나네요. 오늘은 저와 함께 이 ‘사소하지만 중요한’ 예외 상황들을 어떻게 해결했는지, 그 공부의 흔적을 나눠보려 합니다.

자바스크립트 계산기 메인 화면

1. 고민했던 점

프로젝트를 진행하며 제가 가장 깊게 고민했던 세 가지 포인트를 골라봤습니다.

① ‘0’이 두 번 연속으로 나오는 건 막아야죠!

처음 화면이 0일 때 숫자를 누르면 01이 아니라 바로 1이 되어야 하잖아요? 이 당연한 기능을 구현하기 위해 조건문을 활용했습니다.
이 짧은 코드 한 줄 덕분에 계산기가 훨씬 ‘진짜’ 같아졌을 때의 그 기분, 여러분도 느껴보셨으면 좋겠어요!

function appendToDisplay(input) {
    // 현재 화면이 '0'이고, 소수점이 아닌 숫자를 새로 입력받을 때의 처리
    if (display.value === "0" && input !== ".") {
        display.value = input; // '0'을 지우고 새 숫자로 대체!
    } else {
        display.value += input; // 그 외에는 뒤에 덧붙이기
    }
}

② 문자열을 계산으로 바꾸는 마법

우리가 화면에 입력한 값은 사실 숫자 형태가 아니라 ‘1+2’ 같은 ‘문자열’입니다. 이걸 어떻게 실제 계산 결과로 바꿀 수 있을까 고민하다가 new Function을 활용하는 법을 배웠습니다.

기존 생각: eval()을 쓰면 편하다던데?

새로 배운 점: 하지만 보안상 위험할 수 있구나! 조금 더 안전한 방법을 찾아보자. 이런 식으로 하나씩 더 나은 대안을 찾아가는 과정이 코딩 공부의 진짜 묘미인 것 같습니다. 그래서 사용한 방법이 new Function을 활용한 방법입니다.

function calculate() {
    try {
        // eval 대신 Function을 사용하는 조금 더 안전한 방법
        display.value = new Function('return ' + display.value)();
    } catch (error) {
        display.value = "Error";
        setTimeout(clearDisplay, 1500);
    }
}

③ DEL 키의 구현

전체 삭제인 AC 버튼은 쉽게 구현이 가능하지만, DEL 버튼의 경우에는 마지막 글자 한 개만을 삭제해야됩니다. 그래서 사용한 방법이 slice(시작, 끝)라는 메서드입니다. 문자열의 시작 index부터 끝 index까지 추출 하여 배열로 반환합니다.

function deleteLast() {
    display.value = display.value.slice(0, -1);
    if (display.value === "") display.value = "0";
}

display.value.slice(0, -1)와 같이 끝 index의 수가 음수인 경우에는 끝에서부터 두 번째 값까지 추출하라는 의미입니다. 그래서 앞선 코드 같은 경우 시작 문자열 처음부터 끝에서 두 번째 값까지 추출하라는 의미가 되죠. 전체 문자열 중에서 마지막 문자열만 잘라내는 방식입니다.

계산기의 숫자 처리 방식은 [자바스크립트 환율 계산기]를 만들 때 기본 토대가 됩니다.

2. 자바스크립트 계산기 HTML 코드

이번에도 HTML 코드는 크게 어려운 것이 없습니다. 필요한 버튼만 생성해주었습니다.
실제 사용되는 프로그램으로 만들기 위해서는 디자인적인 요소를 많이 추가해주시면 됩니다.

자바스크립트 계산기 HTML 구조

3. 자바스크립트 계산기 CSS 내용

계산기의 버튼들을 가로세로 딱딱 맞게 배치하는 게 생각보다 어렵더라고요. 이번에 처음으로 CSS Grid를 제대로 써봤는데, grid-template-columns: repeat(4, 1fr); 이 한 줄로 버튼들이 정렬되는 걸 보고 정말 짜릿했습니다. 디자인이 깔끔해지니 제가 만든 프로그램에 대한 애정도 더 생기더라고요.

처음에는 일반적인 회색 버튼을 넣었는데, 계산기라면 연산자 버튼에 포인트 컬러가 있어야 할 것 같더라고요. 그래서 아이폰 계산기 느낌을 살려 오렌지색(#ff9f0a)을 입혀봤습니다. 버튼에 마우스를 올렸을 때 살짝 밝아지는 hover 효과까지 넣으니 훨씬 생동감이 생기더라고요. CSS의 작은 수치 하나가 사용자 경험을 이렇게 바꿀 수 있다는 걸 다시 한번 배웠습니다.

4. 자바스크립트 계산기 실행 화면

5. 보완점

계산기를 완성하고 나니, 당장은 구현하지 못했지만 앞으로 꼭 채워보고 싶은 숙제들이 남더라고요.

  1. 히스토리(기록) 기능: 내가 이전에 어떤 식을 계산했는지 로그를 남겨서 리스트로 보여주는 기능을 추가하면 좋을 듯 싶습니다. 나중에 저번시간에 공부한 LocalStorage를 추가하여 연동해 보면 재밌을 것 같습니다.
  2. 키보드 입력 지원: 지금은 마우스로 버튼을 클릭해야 하지만, 실제 계산기처럼 숫자 키패드로도 입력이 가능하게 keydown 이벤트를 연결해 보면 훨씬 사용자에게 좋은 사용감을 줄 수 있을 것 같습니다.
  3. 소수점 정밀도 해결: 자바스크립트 특유의 부동 소수점 오차때문에 0.1 + 0.2를 계산하면 0.30000000000000004 같은 이상한 값을 내놓는다는 걸 알게 되었어요. 0.1 + 0.2가 정확히 0.3이 나오도록 toFixed() 같은 메서드를 추가하면 좋을 것 같습니다.

완성된 계산기로 1+1을 눌러 2가 나오는 걸 확인했을 때, 그 당연한 결과가 왜 그렇게 기뻤는지 모릅니다. 아마 단순히 코드를 복사한 게 아니라, 연산자가 꼬이지 않게 고민하고 삭제 버튼(DEL)의 로직을 직접 짜봤기 때문이겠죠?

계산기 로직을 짤 때 가장 까다로웠던 점은 연속으로 연산자를 누르거나 소수점을 중복으로 입력할 때 발생하는 예외 처리였습니다. eval() 함수를 쓰면 편하지만 보안상 좋지 않다는 점을 배우고, 직접 조건문을 활용해 연산 로직을 구현해 보았습니다.

여러분도 계산기를 만들면서 “왜 이건 안 되지?” 하고 막히는 순간이 분명 있을 거예요. 그럴 때 포기하지 마시고, 저처럼 하나씩 조건문을 추가해 가며 여러분만의 해결법을 찾아보셨으면 좋겠습니다. 혹시 로직이 꼬여서 도움이 필요하시거나, 더 멋진 아이디어가 떠오르신다면 언제든 댓글로 같이 고민해 봐요! 우리 다음 프로젝트에서도 함께 성장해 봐요!

댓글 남기기