Thr*_*ion 5 javascript closures
我试图在我的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...
}
Run Code Online (Sandbox Code Playgroud)
所以稍后在我的应用程序中如果我需要回到我调用storeState时我可以做的那一点
//return the object I put in my closure
var backToNormal = savedFeature.savedItem();
Run Code Online (Sandbox Code Playgroud)
因为我调用storeState()后对savedFeature对象的任何更改都会反映在从被调用的savedItem()中检索的项目中,但这不起作用.我猜这种情况正在发生,因为闭包被设置为self的引用而不是复制到新实例.
反正有没有将我的整个对象的状态存储在这样的闭包中,或者我需要以其他方式存储它.
您遇到的问题是在 js 中对象是通过引用传递的。这意味着对您的对象执行的所有更改都将应用于您的obj.savedItem属性。
修复:将深度克隆存储到obj.savedItem
this.storeState = function() {
this.savedItem = _.cloneDeep(this); // or _.clone(this, true);
}
Run Code Online (Sandbox Code Playgroud)
cloneDeep是一种lodash方法,大多数 js 库都提供自己的方法,例如 jQuery 的$.extend等。
您可以轻松地推出自己的深度克隆功能,查找此线程上的选项。
一个完整的 jQuery 示例:
function SavedFeature() {
this.savedItem;
this.clone = function() {
return $.extend(true, {}, this);
},
this.storeState = function() {
this.savedItem = this.clone();
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以通过更改clone方法来适应不同的环境,因为它是使用的库方法的外观。