자바스크립트로 계산기 만들어보기 — 2

Designer
6 min readFeb 3, 2019

--

어디까지나 stock 이미지입니다..(..)

이전 글에선 계산기의 숫자를 누르면 입력칸에 숫자값이 입력되는 것까지 진행했다.

이번에는 연산작업까지 진행할 것이다.

이전 작업에서 진행한 계산기는 버튼들을 누르면 인풋에 버튼에 해당하는 값들을 보여준다. 하지만 값들이 그대로 입력이 되고 연산이 되지 않는다.

이제 입력된 값들이 연산이 되도록 해보자.

계산기에 누른 버튼의 값을 하나씩 보여주기

보통 일반 계산기를 누르면 누른 값들을 연속으로 나열해서 보여주지 않고 누른 값들을 하나씩 누를 때마다 보여준다. 이러한 방식을 내가 만들 계산기에도 적용하기로 했다.

var oldval = $inval.val();
var result = oldval+newVal;
$inval.val(result);

먼저 자바스크립트에서 위코드들을 지워주고

var $header = $(".calc-header");
var $body = $(".calc-body");
var $buttons = $("button");
var arr = []; // 빈 배열추가

입력한 값을 저장할 수 있도록 위에서 배열을 미리 만들어 둔다.
변수는 하나의 값만 저장할 수 있지만 배열은 여러 개의 값을 저장할 수 있다.
배열에 대한 자세한 설명은 이쪽을 참고바란다.

기존에는 oldval이라는 변수를 이용해서 값을 저장해줬다면 이제는 배열을 이용해서 값을 저장할 것이다.

이제 버튼을 눌렀을 때 일어날 동작들을 수정해준다.

$buttons.click(function(){
var newVal = $(this).val(); //
$(this) = 누른 버튼
if (newVal==="=") {
return false;
}
//'='버튼을 눌렀을 때
arr.push(newVal); //배열(arr)에 누른 값을 넣어줌
var lastNumber = arr[arr.length-1];
//
배열[배열의 요소 갯수 - 1], 마지막에 입력한 값을 변수에 담아준다.
var $inval = $("#inval");
$inval.val(lastNumber);
//
인풋에 마지막에 입력한 값을 담은 변수를 넣어줌
});

if (newVal === “=”)라는 조건을 넣어준다. 즉 ‘=’ 버튼을 눌렀을 때는 함수실행을 종료시키고 어떤 행동도 일어나지 않도록 한다.

입력한 값들을 배열에 넣어주고, 인풋에는 입력한 값들 중 마지막 값을 보여주도록 한다.

인풋에 입력한 값들 중 마지막 값을 구하는 방법은 배열의 길이 length 를 이용하면 된다. 배열의 길이는 배열 안에 저장된 요소의 갯수를 뜻한다.

[ ] 이 괄호 안에 가져오고 싶은 요소의 순서번호를 적어주면 된다.
만약 첫번째로 누른 버튼의 값을 가져오고 싶을 경우 arr[0]이라고 적어주면 된다. 이때 [] 괄호 안에 들어가는 숫자는 보통 인덱스라고 부르며 인덱스는 1이 아닌 0부터 시작한다.

var lastNumber = arr[arr.length-1];
//
배열[배열의 요소 갯수 - 1], 마지막에 입력한 값을 변수에 담아준다.

때문에 마지막 값을 가져오고 싶을 경우 arr.length 가 아니라 -1을 해준 값을 인덱스로 넣어줘야한다.

var $resultBtn = $("#result-btn"); //'='의 id값을 변수에 저장해준다.
$resultBtn.click(function(){
//'='버튼을 클릭했을 때
for(var i = 0; i < arr.length; i+=1) {
console.log(arr[i]);
}
//배열에 담긴 요소 길이만큼 배열 안을 순회. 콘솔창에서 요소가
차례대로 잘 담긴 것을 확인
});

마지막으로 배열에 누른 값들이 모두 잘 저장되었는지 반복문을 통해 확인해볼 수 있다. 아래는 수정한 자바스크립트 코드 전체이다.

이 반복문을 활용해서 배열에 담긴 값들을 하나의 문자열로 만들 것이다.
( 문자열이어야 값들을 계산할 수 있기 때문. 이부분은 뒤에서 설명할 것)

값을 하나씩 보여주도록 수정한 index.js파일

드디어 (!) 연산기능 추가

함수 실행 종료 조건 추가

먼저 버튼을 눌렀을 때 함수 실행 종료에 해당되는 조건을 한가지 더 추가해준다.

if (newVal==="=") {
return false;
}

//누른 버튼이 ‘=’ 일 때 함수 실행 종료
if(arr.length === 0 && (newVal==="*" || newVal==="/")) {
return false;
}
//
배열에 담긴 요소가 없고 누른 버튼이 ‘*’ 또는 ‘/’ 일 때 함수 실행 종료

배열에 숫자값이 없을 때 곱하기나 나누기를 할 경우 연산을 할 수 없기 때문에 함수 실행을 종료시킨다.

연산함수 추가

값을 계산하기 위해서 연산을 해주는 함수인 eval을 추가해준다.
eval함수는 자바스크립트에 내장된 함수로 문자열을 계산해준다. 이처럼 문자열만 해석이 가능하고 배열은 안되기 때문에 문자열로 값을 만들어서 주어야 계산이 가능하다.

eval에 대한 자세한 설명과 예시는 이쪽을 참고

$resultBtn.click(function(){        var str = ""; //빈 문자열 생성        for(var i = 0; i < arr.length; i+=1)    {
str = str + arr[i];
}

//문자열에 배열에 담긴 값들을 차례대로 넣어줘서 하나의 문자열로 생성
var result = eval(str);
//값이 담긴 문자열을 eval함수로 계산해서 변수에 저장
var $inval = $("#inval");
$inval.val(result); //계산된 값이 담인 변수를 인풋에 넣어줌
arr = []; //배열을 빈 배열로 초기화
});

인풋에 계산된 값을 보여준 다음에는 기존 계산기처럼 새로운 계산을 할 수 있도록 기존 값이 담겨있던 배열을 빈 배열로 초기화한다.
아래는 수정된 자바스크립트 전체 코드이다.

연산함수가 추가된 index.js

이제 숫자와 연산자를 눌러보면 계산이 되는 것을 확인해볼 수 있다.

잠깐.. 숫자가 무조건 한자리수만 입력이 되는데요..? 😰

이제 연산은 되지만 아직 문제가 남아있다.

  1. 숫자가 한자리 수 이상 입력이 안됨
  2. 숫자를 0으로 나눴을 때 에러발생 (인풋에 infinity 값 출력)

위 두가지는 다음편에서 해결해보도록 하겠다.

--

--