TyperScript / 계산기 프로젝트

@BINI·2025년 2월 27일
0

요새 typeScript 공부중/간단하게 프로젝트 코드 설명하고 공부 기록 남길 예정임

[구현화면]

  • 구현한 화면은 위와 같음 html 마크업 및 css는 생략하고 js만 설명

[typescript 코드]

let calcArray: (number | string)[] = []; // 계산할 값을 저장할 배열
let inOperCheck: boolean = false;  // 연산자 체크 (true일 경우, 숫자 입력)
let resultNum: boolean = false;  // 계산 완료된 상태 체크
let currentNum: string = "";  // 입력 중인 숫자
let result: number = 0;  // 결과 값 저장

// .calc_input
let calcInput: HTMLInputElement | null = null;
document.addEventListener("DOMContentLoaded", () => {
    calcInput = document.querySelector(".calc_input") as HTMLInputElement;
});

// 숫자 클릭 시 calcInput으로 값 추가
const inputNum = (event: MouseEvent) => {
    let btn = event.target as HTMLButtonElement;

    // 계산 완료 후 숫자 클릭 시 초기화
    if (resultNum) {
        resetCalculator();
    }

    resultNum = false;
    inOperCheck = true;
    currentNum += btn.textContent!;  // 숫자 입력 시 계속 이어 붙여줌
    calcInput!.value = currentNum;  // calcInput에 현재 숫자 표시
};

// 연산자 클릭 후 계산을 위한 함수 (연산자별 함수 통합)
const handleOperator = (operator: string) => {
    if (resultNum) {
        resetCalculator();
        currentNum = result.toString(); // 이전 계산된 결과를 currentNum에 할당
        calcArray = [result]; // calcArray에 결과값만 추가
        calcInput!.value = currentNum; // calcInput에 결과값만 표시
    }

    if (inOperCheck) {
        if (currentNum) {
            calcArray.push(Number(currentNum));  // 현재 입력된 숫자를 배열에 추가
        }
        calcArray.push(operator);  // 연산자 추가
        currentNum = "";  // 연산자 후에는 currentNum 초기화
        calcInput!.value += operator;  // calcInput에 연산자 추가
    }

    inOperCheck = false;
};

// 각 연산자 처리 함수
const calcPlus = () => handleOperator("+");
const calcMinus = () => handleOperator("-");
const calcMultiply = () => handleOperator("*");
const calcDivision = () => handleOperator("/");

// 계산 결과 출력
const inputResult = () => {
    if (currentNum) {
        calcArray.push(Number(currentNum));  // 마지막 입력된 숫자도 배열에 추가
    }

    result = calcArray.reduce((acc: number, item: string | number, index: number, array: (string | number)[]) => {
        if (index === 0) {
            return Number(item);  // 첫 번째 값은 숫자로 변환
        }

        let currentOper: string = array[index - 1] as string; // 연산자
        let nextNumber: number = Number(item); // 숫자형으로 변환

        // 연산자에 따라 계산
        switch (currentOper) {
            case "+":
                return acc + nextNumber;
            case "-":
                return acc - nextNumber;
            case "*":
                return acc * nextNumber;
            case "/":
                return acc / nextNumber;
            default:
                return acc;
        }
    }, 0);  // 초기값 0

    calcInput!.value = result.toString(); // 결과를 calcInput에 출력
    resultNum = true;  // 계산 완료 상태
    calcArray = [result];  // calcArray를 계산된 결과로 초기화
};

// 계산기 초기화 함수
const resetCalculator = () => {
    calcInput!.value = "";  // calcInput 초기화
    calcArray = [];  // calcArray 초기화
    currentNum = "";  // currentNum 초기화
    resultNum = false;  // 계산 완료 상태 초기화
};
  1. 사용자가 클릭한 값을 배열에 담아서 =을 클릭하면 담긴 배열에 따라 계산되게 함수 제작
  2. 기본값 추가 필요 (변수를 미리 만들어 준비하는 과정)
  • 사용자가 클릭한 값 즉, 계산할 값을 저장할 배열 > calcArray
  • 사용자가 여러자리의 숫자를 계산할 경우의 수를 위해 연산자를 체크하는 불리언 변수 세팅 > inOperCheck
  • =을 클릭시 계산이 완료됨 이때, 연산자를 클릭시 계산된 결과값에 연산하기 위해 계산 완료 여부를 체크하는 불리언 변수 세팅 > resultNum
  • 현재 입력된 숫자 확인 변수 세팅(연산자도 같이 추가되서 문자열로 변수세팅) > currentNum
  • 결과 값 저장하는 넘버 변수 세팅 > result
  1. 이제 모듈별로 함수를 추가
  • 숫자 클릭시 숫자가 배열에 담기고 calcInput에 추가되는 함수 > inputNum
  • 연산자 클릭시 배열에 연산이 담기도록 함수 > handleOperator
    ※ 이때, 연산 계산 함수를 만들고 각 연산하는 함수도 따로 만든다.(반복 코드를 없애기 위한 과정임) 그리고 각 연산하는 함수에 인자에 연산자를 넣어 배열에 담기도록 함수 제작
  • 이제 담긴 배열을 = 클릭시 계산하는 함수 제작 > inputResult
  • c 클릭시 배열 및 값이 완전 초기화되는 함수(사용자가 새로운 계산을 하거나 오류 등 대비하기 위한 버튼)

대략 위와 같은 구조로 함수를 설계함.

★★★ 프로젝트하면서 느낀 점(이건 퍼블 실무하면서 느낀점도 포함)
1) 초기화함수 : 제일 첫번째로 넣기(현재 제일 마지막에 한건 잘못된듯)

  • 초기화함수는 반드시 필요함
  • 초기화함수는 반드시 따로 분리해서 사용(타함수에도 적용될 수 있게 따로 분리되어야함)
    2) 함수형식 통일화
  • 화살표 함수 쓸건지 일반 함수 쓸건지 형식을 정해야함.
    그리고 익명함수 쓸건지 클래스명으로 지정해서 함수 쓸건지도 정해야함
  • 유지보수면에선 익명함수가 훨씬 사용하기 편함
  • 난 회사에서 객체함수를 사용했지만 공부해보니 화살표 함수가 훨씬 보기 편하고 사용이 용이한거 같음. this사용여부가 더 광범위하다고 느낌 (그리고 모듈화하기도 더 편함)
    3) var쓰지말고 let 쓰기
  • let이 좀더 명확함 let은 error를 바로 발생시키기 때문에 명확함 var 쓸거면 굳이 typescript 안써도 될거같음
    4) typeScript로 작업하니 더 오래 걸림
  • 일반 script에 비해 변수마다 형식을 지정해야하니 작업이 오래걸리는 면이 있음
  • 그러나 내가 변수를 짤때 더 명확하게 계획하고 구조를 짤 수 있어서 더 체계적인 면이 있음
    그러니까 환경이 나를 더 구체화시키는 느낌이 들었음
    5) 변수명이나 함수명을 더 명확하게 쓰는 공부가 필요할 거 같음
  • 내가 퍼블 실무하면서 개발자들이 지적한 부분 중 하나임
  • 이 변수가 무엇을 의미하는 지, 함수명이 무엇을 의미하는 지 잘모르겠다한 부분
    그리고 모듈화가 제대로 되어있지 않고 부분적으로 함수가 연결되어있다고 했었음 (나도 그렇게 느낌)
  • 그런 부분을 방지하려면 주석을 달아서 이게 무엇인지 하나하나 체크하면서 나 스스로도 확인하는 시간을 가져야할 거 같음

★★ 그 외 내 생각
1) 나는 프론트앤드 개발자가 되고 싶다라기 보다 이 웹이라는 분야가 재밌고 광범위해서 좋다.
배우면 배울수록 우주같다. 파도파도 끝이 없는 이 분야가 좋을 뿐이다. 아직 내가 알고 있는건 일부분이고 그 일부분에서도 내가 주니어를 조금씩 벗어나고 있다는 사실자체도 흥미롭다.

profile
일단 하고, 끝까지 하기

0개의 댓글