2

JavaScript や Google v8 エンジン用の永続化フレームワークはありますか?

オブジェクト (関数などを含む) のグラフ全体を保存 (シリアル化) し、後で再読み込みしたいと考えています。JSON は、関数の格納を許可せず、ツリー状の構造しか許可しない (つまり、同じオブジェクトを参照する 2 つのオブジェクトがない) ため、十分ではありません。

プログラムのユーザーが JavaScript でカスタマイズできるようにしたいので、一般的に (つまり、v8 を埋め込んだプログラムを作成する時点で JavaScript コードを知らなくても) できるようにする必要がありますが、プログラムの状態 (カスタマイズの状態を含む) を保存し、後で再ロードします。したがって、JavaScript エンジンの状態を保存する必要があります。

編集:

例:

次のコードがあるとします。

var obj = { a: 4, b: function (x) { return x + this.a; } }
// ...
if ( ... ) { obj.a = 5; }
// ...
if ( ... ) { var c = 1; obj.b = function (x) { return x + this.a + c; } }
// ...
// now I want to serialize obj

次に、(プログラムのロジックに関するメタ情報なしで)objシリアライズして後でデシリアライズしてobj.b (2)、シリアライズ前と同じ結果をデシリアライズ後に配信することは可能ですか?

2 番目の編集:閉鎖に注意してください。

4

3 に答える 3

6

残念ながら、あなたがやろうとしていることは現在 Javascript では不可能です。その理由は、クロージャーは単なるオブジェクトではなく、実行コンテキストにバインドされたオブジェクトだからです。

「これは JavaScript では実行できません」という問題を乗り越えて、回答の「これを許可する V8 用のパッチを書いたらどうなるか」という段階に進むと、これは概念的に困難です。基本的に、シリアル化するクロージャーごとにContext、クロージャーが存在するオブジェクトをシリアル化する必要があります。 をシリアル化できるのはいいことですHandleScopeが、クロージャーの性質上、それらの内部にはアクセスできません。 .

では、クロージャーが存在する Context をシリアライズできる関数を作成し、デシリアライズすることもできるとしましょう。あなたはそれで何をしますか?

それに対する答えは「あまりない」です。Javascript は、一度に 1 つのコンテキストでのみ実行できます。逆シリアル化したクロージャーは、プルしようとしているコンテキストには存在しません。コンテキスト間でデータを実際に渡すことはできません。関数に自由変数にバインドされたデータがある場合、デシリアライザーを呼び出すコンテキストに存在するものを使用しますか、それともデシリアライズされたコンテキストで上書きしますか? 概念的には、これは悪夢です。

Ecmascript Harmony は、ほぼファーストクラスの継続を提供することを検討していましたが、私がここで怒鳴っている議論から押し出されましたが、これはすぐには実現しません。

于 2012-09-27T17:28:33.543 に答える
0

関数の永続化は良い習慣ではないと思います。以下のアプローチを提案できます。JSON データを "MyData" のようなクラスに変換します。fromJSON と toJSON の 2 つの関数を見つけることができます。これらは、必要な魔法を実行します。

var MyData = function(props){

    this.temp = "a";

    this.getTemp = function(){
        return this.temp;
    }

    this.fromJSON = function(props){
        if(props){
            this.temp = props.temp;
        }

    }
    this.toJSON = function(){
        var props = {};
        props.temp = this.temp;
        return props;
    }

    this.fromJSON(props);

}

var obj = new MyData({"temp" : "b"});
var state = obj.toJSON();
// persist state about the object as JSON string
LOCALSTORAGE.put(state); // You can write some HTML5 local storage stuff to persist

var persistedState = LOCALSTORAGE.get(); // You can use the above HTML5 local storage stuff to read the persisted stuff
var newBornObj = new MyData(persistedState);
于 2012-10-02T10:07:18.997 に答える