2011-10-16 15 views
5

Javascriptアプリケーションの場合、ユーザーにオブジェクトの状態を保存させる必要があります。これには、以前に動的に作成されたカスタム関数、またはGUIを使用して保存された一連のカスタム関数を保存し、後でこれらの関数をロードします。基本的には、関数を直列化してシリアル化する必要があります。JavascriptのFunction.toString()の逆操作

は、今私はFunctionオブジェクトの.toString()メソッド使用してシリアル化パーツを達成:

func.toString().replace('"', '\"').replace(/(\r)/g, ' ').replace(/(\n)/g, ' ').replace(/(\t)/g, ' ') 

これは私を与えるが、この美しさのような「シリアライズさ」機能は、(関数に名前があることに注意してください):

私は苦労ところ、これをUnserializing
"function (someParameter) {this.someFunctionName(return 'something';}" 

です。私はそれにeval()を呼び出す前t =でシリアル化された機能を付加する方法

var func = eval('t =' + so.actions[i].func); 

注:機能をunserializingための私の現在の最善の解決策はこれです。私はグローバル変数を作成するので、これを行うのが好きではありませんが、その周りに道を見つけることができません。機能が、undefinedを返さないvar t =、evalのを()先頭に追加すると

別の方法が「アンシリアライズ」無名の機能はあります

。:これを付加しない場合、私は、「予期しないトークン(にSyntaxError」を受け取ります。?

PS:ユーザー入力にeval()を使用することのセキュリティへの影響を認識しています。近い将来、私はこのソフトウェアの唯一のユーザーですので、現在は問題ではありません。

答えて

6

Functionコンストラクタを使用してグローバル変数を作成しないようにします。

var func = Function("return " + so.actions[i].func)(); 

これは同等です:を警戒するために

var func = eval("(function() { return " + so.actions[i].func + " })()"); 

ことの一つは、関数内の変数を使用して、シリアライズ「変更」とデなりますので、あなたは、キャプチャすることができなくなり、周囲の閉鎖でありますシリアライズ。

編集

私は考えていないよ、あなたはもちろん、単に行うことができます。

var func = eval("(" + so.actions[i].func + ")"); 
+0

閉鎖が世話をしています。これらの関数は 'Function.call(theContextTheFunctionIsExecutedIn)'を使ってのみ実行されます。それはあなたの提案を除いて、括弧で連載された関数を囲むことができます - あなたはなぜ知っていますか? – jonemo

+1

[MDN](https://developer.mozilla.org/ja/JavaScript/Reference/Functions_and_function_scope)によると、括弧を追加すると、関数*宣言*から関数*式*に変更されます。 (これは括弧内の式の一部です)。これは式なので、値を返すので、 'func'に代入することができます。これは、評価が現在行われている範囲によっても異なる場合があります。 –

+0

http://kangax.github.com/nfe/も参照してください。 – user123444555621

0

これは動作するはずです:

eval('var func = ' + so.actions[i].func); 
関連する問題