存储JavaScript对象的状态

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的引用而不是复制到新实例.

反正有没有将我的整个对象的状态存储在这样的闭包中,或者我需要以其他方式存储它.

mar*_*ebl 2

您遇到的问题是在 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方法来适应不同的环境,因为它是使用的库方法的外观。