2012-09-23 83 views
1

JavaScript和/或Google v8引擎是否有任何形式的持久框架?JavaScript/Google v8的持久框架

我想存儲(序列化)對象的整個圖形(包括,例如,函數)並稍後重新加載它。 JSON是不夠的,因爲它不允許存儲函數,只允許樹形結構(即沒有兩個對象引用同一個對象)。

因爲我希望我的程序的用戶能夠使用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)在序列化之後提供與序列化之前相同的結果?

第二編輯:注意關閉。

+0

我不明白你爲什麼需要堅持功能?因爲您可以從對象原型繼承中恢復函數(假設方法)。 –

+0

你的問題對我來說並不完全清楚。儘管如此,我仍然試圖通過一個例子來說明我的問題。 – JohnB

+0

爲什麼不只是存儲所有的JavaScript代碼,然後評估恢復它(就像從服務器回來)?或使用'toString()'來反序列化每個函數。再次評估無法避免。 –

回答

0

HTML5本地存儲允許通過javascript在客戶端級別進行持久化。

我不確定它是否適合您的需求,至於能夠存儲一個函數,您需要稍微給它一些標記,以便在從存儲中檢索它時反序列化它(或者只是存儲它爲純文本,並嘗試EVAL它檢索)

http://diveintohtml5.info/storage.html

+0

嗯,存儲函數爲純文本的問題是,如果函數涉及閉包,我將丟失捕獲的變量。 – JohnB

+0

您將需要將閉包內部獲得的值複製到函數範圍的變量中。非常可怕,但我認爲它可以做到這一點。 – Bardo

+0

我認爲這個建議最大的問題是它鏈接到w3schools。 W3School不是任何類型信息的可靠來源。 – saml

6

不幸的是,你正在做什麼的Javascript目前不可能。原因是閉包不僅僅是對象,它們是綁定到執行上下文的對象。

通過「這不能在javascript中完成」問題並進入「如果爲V8編寫補丁以允許此答案」階段,這在概念上很困難。從本質上講,對於你要序列化的每一個閉包,你將不得不序列化閉包存在的Context對象。它能很好地序列化HandleScope,但閉包的本質是你無法達到在他們裏面。

好吧,假設您已經編寫了一個函數,可以對封閉存在的上下文進行序列化,您甚至可以對其進行反序列化。你用它做什麼?

答案是「不多」。 JavaScript一次只能在一個上下文中執行。您已經反序列化的閉包並不存在於您試圖將其拉回的上下文中。你不能真正在上下文之間傳遞數據,並且如果你的函數有綁定到自由變量的數據,你是使用存在於反序列化器調用上下文中的數據,還是用反序列化上下文覆蓋它?從概念上講,這是一場噩夢。Ecmascript Harmony已經考慮給我們提供近乎一流的延續,但是這已經成爲討論的焦點,我咆哮了here,但這不會很快發生。

+0

謝謝你這個有見地的答案。然而,我嘗試做的事情是在侏羅紀(C#JavaScript引擎)中實現的,因此Google v8的類似應該不是不可能的。 – JohnB

+0

你如何在侏羅紀做到這一點?我從來沒有使用過它,但我很着迷,知道它是如何工作的。在架構上,我猜測它與V8不同。 – saml

+0

任何理由不接受獲得賞金的答案? – saml

0

我不認爲持久功能是一種好的做法。我可以建議你採用以下方法。把你的JSON數據轉換成像「MyData」這樣的類。你可以從JSON中找到兩個函數,這些函數可以完成你想要的魔法。

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); 
+0

我想你錯過了他被問及如何堅持關閉,而不是JSON。閉包不是JSON能。 – saml