2014-02-12 57 views
5

我試圖在我的javscript對象中存儲'this'的統計信息,以便稍後在我的應用程序中可以將'this'返回到以前的狀態。我認爲我可以完成使用封閉,但到目前爲止我還沒有成功。我的想法是在我的應用程序做這樣的事情JavaScript對象的存儲狀態

function SavedFeature() { 
    var self = this; 

    this.savedItem; 

    this.storeState = function() { 
     this.savedItem = storeClosure(); 
    } 

    function storeClosure() { 
     var closure = self; 
     return function() { 
      return closure; 
     }; 
    }; 

    //other things the user can change... 
} 

所以以後如果我需要回到點,當我打電話storeState我只是做

//return the object I put in my closure 
var backToNormal = savedFeature.savedItem(); 

不工作,雖然因爲我調用storeState()後對我的savedFeature對象所做的任何更改都會反映到從被調用savedItem()中檢索的項目中。我猜這是因爲關閉被設置爲自我引用而不是複製到新實例。

有沒有辦法將我的整個對象的狀態存儲在這樣的閉包中,還是我需要以其他方式存儲這些東西。

回答

2

您遇到的問題是在js中的對象是通過引用傳遞的。這意味着您的對象上執行的所有更改將適用於您的obj.savedItem屬性。

修復:存儲深克隆到obj.savedItem

this.storeState = function() { 
    this.savedItem = _.cloneDeep(this); // or _.clone(this, true); 
} 

cloneDeeplodash方法,大多數JS庫提供的自己,例如一個jQuery的$.extend

您可以輕鬆地推出自己的深層克隆功能,查找此thread上的選項。

使用jQuery一個完整的例子:

function SavedFeature() { 
    this.savedItem; 

    this.clone = function() { 
     return $.extend(true, {}, this); 
    }, 

    this.storeState = function() { 
     this.savedItem = this.clone(); 
    } 
} 

這樣做可以使您通過更改clone方法,因爲它是facading使用的庫方法適應不同的環境。

+0

似乎深度複製是完成整個對象的唯一方法。 – ThrowsException

1

有幾十種方法來實現它。我會做一個簡單的。節約財產。 考慮到如果你想保存整個對象,你需要做深度拷貝的對象

這是你的特點:

function SavedFeature() { 
     this.savedItem = {'isNew': true}; 
     this.stateMachine = new StateMachine(); 
} 

這是某種狀態機:

function StateMachine() { 
     var state = { 'isNew' : null}; 
     function set(newState) { 
     state.isNew = newState.isNew; 
     } 
     function get() { 
     return state.isNew; 
     } 
     return { 
     get : get, 
     set : set 
     }; 
    } 

其中,知道如何存儲是否新款財產

和工作示例:

var savedFeature = new SavedFeature(); 
console.log(savedFeature.savedItem); // true by default 

savedFeature.stateMachine.set(savedFeature.savedItem); // saving state. 
savedFeature.savedItem.isNew = false; // modifying state 
console.log(savedFeature.savedItem); // return false, because of statement above 

var restoredState = savedFeature.stateMachine.get(); // restoring state 
console.log(restoredState); // true 

savedFeature.savedItem.isNew = restoredState.isNew; 
console.log(savedFeature.savedItem); // true 

您可以調整該代碼並根據需要實現功能。希望有幫助