我试图在我的javscript对象中存储'this'的统计信息,以便稍后在我的应用程序中我可以将'this'返回到先前的状态。我以为我可以用封闭来完成,但到目前为止我还没有成功。我的想法是做这样的事情
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()中检索的项目中,但是不起作用。我猜这种情况正在发生,因为闭包被设置为self的引用而不是复制到新实例。
无论如何都要将我的整个对象的状态存储在这样的闭包中,或者我是否需要以其他方式存储它。
答案 0 :(得分:2)
您遇到的问题是js对象是通过引用传递的。这意味着对您的对象执行的所有更改都将应用于您的obj.savedItem
属性。
修复:将深层克隆存储到obj.savedItem
this.storeState = function() {
this.savedItem = _.cloneDeep(this); // or _.clone(this, true);
}
cloneDeep
是lodash方法,大多数js libs提供自己的方法,例如jQuery的$.extend等等。
您可以轻松滚动自己的深度克隆功能,在thread上查找选项。
jQuery的完整示例:
function SavedFeature() {
this.savedItem;
this.clone = function() {
return $.extend(true, {}, this);
},
this.storeState = function() {
this.savedItem = this.clone();
}
}
这样做可以让您通过更改clone
方法来适应不同的环境,因为它正在使用已使用的库方法。
答案 1 :(得分: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
};
}
,知道如何存储 isNew 属性
和一份工作样本:
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
您可以调整该代码,并根据需要获得功能。希望有所帮助