0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

javascriptでeval使わず電卓作成する方法

Posted at

はじめに

javascript勉強初心者です。
簡単なコードの書きたかたを、本屋やネットで学んで、次は何をしようかとネットで検索しながら考えていたところ、とりあえず初心者は小さなコードを沢山書くのがいいとのことで、電卓作成がいいとあったので、作ってみました。
ネットで調べながらコードを書いていたところ、ネットにあったコードのjavascripの組み込み関数evalは、セキュリティに不安があるというのを見かけたため、evalを使わない方法で電卓を作成してみました。
※この内容は、AIを用いて一部作成していますが、検証は行っており、簡単な計算はできる電卓としての機能は達成できていることを確認しています。

script.js
function calculateExpression(expressionArray) {
    const numbers = [];
    const operators = [];
    const precedence = { '+': 1, '-': 1, '*': 2, '/': 2 };

    function applyOperation() {
        const b = numbers.pop(); // 最後の数値を取得
        const a = numbers.pop(); // その前の数値を取得
        const op = operators.pop(); // 最後の演算子を取得

        switch (op) {
            case '+': numbers.push(a + b); break;
            case '-': numbers.push(a - b); break;
            case '*': numbers.push(a * b); break;
            case '/': numbers.push(a / b); break;
        }
    }

    for (let item of expressionArray) {
        if (typeof item === 'number') {
            numbers.push(item); // 数字なら numbers に追加
        } else {
            while (
                operators.length > 0 &&
                precedence[operators[operators.length - 1]] >= precedence[item]
            ) {
                applyOperation(); // 計算を実行
            }
            operators.push(item); // 新しい演算子を追加
        }
    }

    while (operators.length > 0) { // 残りの演算子を計算
        applyOperation();
    }

    return numbers[0]; // 計算結果を返す
}

const display = document.querySelector('.display');
const buttons = document.querySelectorAll('.calc-button');

buttons.forEach(button => {
    button.addEventListener('click', () => {
        if (button.value === 'C') {
            display.value = ""; // ディスプレイをクリア
        } else if (button.value === '×') {
            display.value += '*'; // 演算子を適切な形に変換
        } else if (button.value === '÷') {
            display.value += '/'; // 演算子を適切な形に変換
        } else if (button.value === '=') {
            // 計算を実行
            const expressionArray = display.value.match(/(\d+|\+|\-|\*|\/)/g).map(item => {
                return isNaN(item) ? item : Number(item); // 数字なら数値に変換
            });
            const result = calculateExpression(expressionArray); // 計算
            display.value = result; // 結果を表示
        } else {
            display.value += button.value; // 数字または演算子を追加
        }
        console.log(display.value); // デバッグ用
    });
});
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="scss/style.css">
    <script src="js/script.js" defer></script>
</head>
<body>
    <table>
        <tr>
            <td colspan="4">
                <input type="text" class="display" value="" disabled>
            </td>
        </tr>

        <tr>
            <td><input type="button" value="7" class="calc-button"></td>
            <td><input type="button" value="8" class="calc-button"></td>
            <td><input type="button" value="9" class="calc-button"></td>
            <td><input type="button" value="÷" class="operator calc-button"></td>
        </tr>

        <tr>
            <td><input type="button" value="4" class="calc-button"></td>
            <td><input type="button" value="5" class="calc-button"></td>
            <td><input type="button" value="6" class="calc-button"></td>
            <td><input type="button" value="×" class="operator calc-button"></td>
        </tr>

        <tr>
            <td><input type="button" value="1" class="calc-button"></td>
            <td><input type="button" value="2" class="calc-button"></td>
            <td><input type="button" value="3" class="calc-button"></td>
            <td><input type="button" value="-" class="operator calc-button"></td>
        </tr>

        <tr>
            <td><input type="button" value="0" class="calc-button"></td>
            <td><input type="button" value="C" class="calc-button"></td>
            <td><input type="button" value="=" class="equal calc-button"></td>
            <td><input type="button" value="+" class="operator calc-button"></td>
        </tr>
    </table>
</body>
</html>
style.css
table {
  width: 500px;
  height: 500px;
  margin: 0 auto;
  border: solid 1px rgba(220, 220, 220, 0.6431372549);
  border-right: solid 4px rgba(220, 220, 220, 0.6431372549);
  border-bottom: solid 4px rgba(220, 220, 220, 0.6431372549);
  border-radius: 10px;
  text-align: center;
  padding: 10px;
}

input {
  width: 100px;
  height: 100px;
  margin: 5px;
  font-size: xx-large;
  background-color: rgba(220, 220, 220, 0.6431372549);
  border: none;
  border-radius: 20px;
}
input:hover {
  background: rgba(116, 115, 115, 0.7254901961);
}
input:active {
  background: #5a5a5a;
}

.display {
  width: 500px;
  height: 100px;
  text-align: right;
  background: #ffffff;
  border-top: solid rgba(220, 220, 220, 0.6431372549) 5px;
  border-bottom: solid rgba(220, 220, 220, 0.6431372549) 5px;
  border-right: solid rgba(220, 220, 220, 0.6431372549) 6px;
  border-left: solid #b6b6b6 6px;
  border-radius: 5px;
}
.display:hover {
  background: #ffffff;
}

.operator {
  background-color: #87cefa;
}
.operator:hover {
  background: #339cdd;
}
.operator:active {
  background: #2c80b4;
}

.equal {
  background-color: #6b6b6b;
}/*# sourceMappingURL=style.css.map */

感想

比較的簡単なプログラムなようですが、調べながら書いたので、少し時間はかかりました。
()や小数点の計算までは作成しきりませんでしたので、また勉強して作成していこうと思います。
今回やってみて、計算一つにしても、PCではこのような動きをしているのかというのを知れて面白かったので、いろいろと簡単なプログラムを作成していこうかなと思います。
初心者なので、ここ違うよなどありましたら、ご指摘いただけると幸いです。
最後までお読みいただきありがとうございました。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?