2014-02-12 59 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 

您可以调整该代码并根据需要实现功能。希望有帮助