このコードは計算機として機能しますが、codeacademy のスクラッチ パッドを見ると、eval が悪であることがわかります。eval を使用せずに同じことを行う別の方法はありますか?
var calculate = prompt("Enter problem");
alert(eval(calculate));
このコードは計算機として機能しますが、codeacademy のスクラッチ パッドを見ると、eval が悪であることがわかります。eval を使用せずに同じことを行う別の方法はありますか?
var calculate = prompt("Enter problem");
alert(eval(calculate));
eval
は文字列入力を JavaScript として評価しますが、偶然にも JavaScript は計算をサポートし、 を理解するため1+1
、電卓として適しています。
を使用したくない場合はeval
、その文字列を自分で解析し、最後に自分で計算する必要があります (正確には自分ではありません)。あなたが望むことをするこの数学プロセッサを見てください。
基本的にあなたがすることは次のとおりです。
たとえば、 がある場合"1+2/3"
、これは次のデータ構造に評価できます。
"+"
/ \
"1" "/"
/ \
"2" "3"
次に、その構造を上から下にトラバースし、計算を実行できます。最初"+"
に、左側に 1 があり、右側に式があるので、最初にその式を評価する必要があります。"/"
2 つの数値の子を持つノードに移動します。それがわかれば、ノード全体を計算してその結果に2/3
置き換えることができます。ここで、再び上に移動して、" " ノード"/"
の結果を計算できます: 。そのノードを結果に置き換えると、残っているのは式の結果だけです。+
1 + 0.66
これがコードでどのように見えるかについてのいくつかの擬似コード:
calculation(operator, leftValue, rightValue):
switch operator {
case '+': return leftValue + rightValue
case '-': return 42
}
action(node):
node.value = calculation(node.operator, action(node.left) action(node.right))
お気づきかもしれませんが、ツリーは演算子の優先順位を尊重するように設計されています。は/
よりもレベルが低く、+
最初に評価されることを意味します。
これを詳細に行うとはいえ、基本的にはそれが進むべき道です。
math.js ライブラリに含まれている式パーサーを使用できます。
使用例:
mathjs.evaluate('1.2 / (2.3 + 0.7)'); // 0.4
mathjs.evaluate('5.08 cm in inch'); // 2 inch
mathjs.evaluate('sin(45 deg) ^ 2'); // 0.5
mathjs.evaluate('9 / 3 + 2i'); // 3 + 2i
mathjs.evaluate('det([-1, 2; 3, 1])'); // -7
入力をフィルタリングすることにより、単純な算術計算機として eval を安全に使用できます。数字、小数点、および演算子 (+、-、、/) のみを受け入れる場合は、大きな問題は発生しません。高度な数学関数が必要な場合は、パーサーの提案を使用することをお勧めします。
function calculate(){
"use strict";
var s= prompt('Enter problem');
if(/[^0-9()*+\/ .-]+/.test(s)) throw Error('bad input...');
try{
var ans= eval(s);
}
catch(er){
alert(er.message);
}
alert(ans);
}
calculate()