存储JavaScript对象的状态

时间:2014-02-12 23:30:33

标签: 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...
}

所以稍后在我的应用程序中,如果我需要回到我调用storeState时我可以做的那样

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

虽然因为在调用storeState()之后对savedFeature对象的任何更改都反映在从被调用的savedItem()中检索的项目中,但是不起作用。我猜这种情况正在发生,因为闭包被设置为self的引用而不是复制到新实例。

无论如何都要将我的整个对象的状态存储在这样的闭包中,或者我是否需要以其他方式存储它。

2 个答案:

答案 0 :(得分:2)

您遇到的问题是js对象是通过引用传递的。这意味着对您的对象执行的所有更改都将应用于您的obj.savedItem属性。

修复:将深层克隆存储到obj.savedItem

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

cloneDeeplodash方法,大多数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

您可以调整该代码,并根据需要获得功能。希望有所帮助