6

結果を生成するために方程式を実行する必要がある Web ページ (150 以上) に多数のフィールドがあります。

現在、次のような方程式を保存しています。

<input name="F7" type="text" class="numeric" data-formula="([C7]-[D7])/[E7]" readonly />

入力がぼやけている場合は、jQuery セレクターを使用してdata-formula属性を持つすべての入力を反復処理し、式を取得し、正規表現を使用してポインター ([C7]式の ) を適切な値に置き換えます。

その後eval()、結果を得るための式を計算し、それを正しい入力に入れます。これはうまく機能しますが、非常に遅く、Web ページが数秒間ハングします。これは、入力がぼやけるたびに発生する場合は悪いことです。

"(1-2)/4" などの式を を使用せずに評価する方法はありeval()ますか? これらの方程式には、平方根などの関数も含まれている場合があり (数式eval()を入力するだけでよいため、これは便利ですMath.sqrt())、数値は 10 進数である場合があります。

注: このアプリケーションは IE7 と 8 で実行する必要があるため、Webworkers などを使用できるとは思えません。「保存」ボタンが押された後にのみこのコードを実行することも検討しましたが、可能であれば UI をライブで更新したいと考えています。

4

7 に答える 7

5

私が本当に知っているのは2つの選択肢だけです。1つはscript、ページに動的に書き込まれる要素を使用することです。例:

function evaluate(formula)
{
  var script = document.createElement("script");
  script.type = "text/javascript";
  script.text = "window.__lr = " + formula + ";";
  document.body.appendChild(script);
  document.body.removeChild(script);

  var r = window.__lr;

  return r;
}

もう1つは使用することnew Function(...)です:

function evaluate3(formula)
{
  var func = new Function("return " + formula);
  return func();
}

evalしかし、http ://jsperf.com/alternative-evaluationと同様のパフォーマンスが得られるものは見つからないと思います。

のパフォーマンスはevalブラウザやプラットフォームによって異なりますが、特定のブラウザとプラットフォームの組み合わせを念頭に置いていますか?改善されたブラウザの新しいjavascriptエンジンは、最適化されたものを提供しますeval

試験結果

これは、いくつかのUAでの限られた一連のテストにすぎませんが、さまざまな環境でどのように実行されるかを理解できるはずです。

于 2012-07-10T22:17:45.087 に答える
4

"(1-2)/4" などの式を を使用せずに評価する方法はありeval()ますか?

式をトークン化し、その動作を模倣する独自のエバリュエーターを作成できますeval。しかし、それは副作用を制限するという点で役立つかもしれませんが (非常evalに大きなハンマーであるため)、実際よりも優れたパフォーマンスを発揮する可能性はほとんどありません.eval

ただし、他のすべての入力を評価した結果をキャッシュして、実際にぼやけた入力のみを評価することができます。それは確かに非常に効率的なはずです。

たとえば、次のグローバル オブジェクトがあるとします。

var values = {
   A7: /* initial value for A7 */,
   B7: /* initial value for B7 */,
   C7: /* initial value for C7 */,
   D7: /* initial value for D7 */,
   E7: /* initial value for E7 */,
   F7: /* initial value for F7 */,
   /* etc */
};

...そして、このblurハンドラーをすべての入力に添付します。

$("input").blur(function() {
    values[this.id] = this.value; // Or parseInt(this.value, 10), or parseFloat(this.value), etc.
    doTheEvaluation();
});

...毎回すべての値を再計算するのではなく、doTheEvaluationからの値を使用しました。values

他のフィールドを参照する可能性がある場合this.valueは、それを再帰的に評価できますが、すべての入力を評価する必要はありません。

于 2012-07-10T21:48:00.543 に答える
1

検証: 入力を検証するための強力な正規表現を作成し、eval安全かどうかを評価するために使用します。

評価: eval の速度について: 大きな問題である場合は、すべての方程式をキューに入れ (配列に格納)、一度にすべて評価することができます。

var equations = ['1+1', '2+2', '...'];   //<-- Input from your fields
var toBeEvald = '[' + equations.join(',') + '];';
var results = eval(toBeEvald);
// result[0] = 2
// result[1] = 4, etc
于 2012-07-10T21:48:41.377 に答える
1

評価を 1 回だけ実行するようにコードを変更します。

var expressions = []
// for each field
// expressions.push("id:" + parsedExpression);
var members = expressions.join(",");
var resultObj = eval("({" + members + "})");
// for each field 
document.getElementById(id).value = resultObj[id];
于 2012-07-10T21:51:44.640 に答える
0

new Function式を評価するために使用できます

于 2015-11-18T08:29:54.983 に答える
0

信頼できるインターネット接続があれば、Google に接続し、Google のサービスを使用して式を評価できます。Google は非常に強力なサーバーを持っており、キューを方程式としてリクエストを送信し、それを取得するだけで済みます。もちろん、これはインターネットの速度/ブラウザの速度に応じて、遅くなったり速くなったりする可能性があります.

または、独自の方程式評価器を作成することもできます。これはかなり難しく、おそらく eval よりも効率的ではありません。また、PEMDAS 注文の膨大なトラブルを経験する必要があります。

方程式を 1 つの文字列に結合し、それを一度に評価して、結果を一度に取得することをお勧めします。

于 2012-07-10T21:54:40.147 に答える