5

new Function(...)非常に削減されたコードから関数を生成するために使用したいと思います。私はこれをしたい

  • 自分で式を解析することを避け、
  • 可能な限り柔軟であること。

eval()私は可能な限り避けます。new Function(...)しかし、セキュリティ ホールが発生しやすいことでも知られている、使用するのに十分な安全性があるかどうかはわかりません。

バックグラウンド

メニューボタンの状態を管理したい。したがって、ボタンを定義しながら、次のようなものを書きたいと思います

 {
 ..., // More button definition
 state: "isInEditmode && (isWidgetSelected || isCursorInWidget),
 ...
 }

いくつかのイベント中に statechange を処理しながら、現在の全体的な状態オブジェクトの状態をstates属性の状態と照合 (要約) します。

したがって、レンダリング時に関数を生成し、DOM 属性ではなく DOMオブジェクト属性としてこのようにアタッチします。

 ...
 $el.stateFn = new Function("stateObj", "with (stateObj) {return " + item.state + ";}");
 ...

テスト状態:

 visible = $el.stateFn.call(currentStates, currentStates);

このwithステートメントは、現在のstateオブジェクトの属性を変数として提供するのに役立ちます。これにより、上記の式で のようなものが必要なくなりますobj.isInEditmode

秘密の質問

私の意見では、DOM オブジェクトに関連付けられた関数はレンダリング時に生成され、ソースから読み取られるため、これによってセキュリティ ホールが発生することはありません。それとも私が間違っていますか?これを避けるべきですか?

Functionパフォーマンスのヒントは高く評価されます (コメント) (レンダリング時に新しいものを 1 回評価する限り、これは許容できると思います)。

編集 1

  • Backbone.js を使用しています。別のフレームワークを使用することは論外です。
  • 一部のメニュー項目は、異なるモデルまたは複数のモデルにバインドする必要があります。
  • 委任 (またはファサード/プロキシ?) モデルは重要です。
4

4 に答える 4

6

ユーザー入力がコード内で発生することが許可されている場合、セキュリティ的にはどちらも同じくらい悪いです。ただし、保守に関しては、ローカルの eval がスコープを台無しにして動的スコープを引き起こす場合に、隠れたバグについて心配する必要はありません。

によって生成される関数のパフォーマンスnew Functionは、他の関数とまったく同じです。生成は遅くなりますがeval、含まれているスコープが最適化されなくなるわけではありません。

実際、new Function次のような状況でパフォーマンスを向上させるために使用できます。

//Will behave like function a( obj ) { return obj.something }
function makePropReader( propName ) {
    return new Function( "obj", "return obj." + propName );
}

構築された関数は、ここで返される関数よりも優れたパフォーマンスを発揮します。

function makePropReader( propName ) {
     return function( obj ) {
         return obj[propName];
     }
}

クロージャーコンテキストから動的に読み取りpropName、オブジェクトが呼び出されるたびに動的読み取りを行う必要があるためです。

于 2013-08-05T15:31:57.583 に答える
1

あなたが自分で書いたコードでのみこれを行うと言ったように、それは問題ないと思います。いずれにせよnew Function()使用するよりも間違いなく優れています。eval()ローカル変数をいじることはなく、を使用して独自のコンテキストを強制していますfn.call

2 方向のデータ バインディングをサポートする MVC または MVVM フレームワークを使用している場合、解決しようとしている問題はかなり簡単に解決できるように思えます。つまり、UI を変更するとバッキング モデルが更新され、モデルを更新すると UI が自動的に更新されます。

たとえば、knockout.jsです。この場合、目に見えるデータバインディングが適切です。

于 2013-08-05T14:52:30.360 に答える