2014-02-12 36 views
5

Ich versuche, die Statistik von 'this' in meinem javscript-Objekt zu speichern, damit ich später in meiner Anwendung 'this' in einen vorherigen Zustand zurückversetzen kann. Ich dachte, ich könnte eine Schließung erreichen, aber bisher war ich nicht erfolgreich. Meine Idee war, so etwas wie dieseSpeicherstatus eines JavaScript-Objekts

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... 
} 

so später in meiner Anwendung zu tun, wenn ich an den Punkt zurückkehren benötigt, wenn ich storeState rief ich nur

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

tun könnte, das allerdings nicht funktioniert weil alle Änderungen an meinem savedFeature-Objekt nach dem Aufruf von storeState() in dem Element im im-Aufruf von savedItem() widergespiegelt werden. Ich vermute, dass dies geschieht, weil die Schließung auf eine Referenz von self gesetzt wird, anstatt auf eine neue Instanz kopiert zu werden.

Gibt es sowieso, um den Zustand meines gesamten Objekts in einer Schließung wie diesem zu speichern, oder muss ich dies auf andere Weise speichern.

Antwort

2

Das Problem, das Sie laufen, ist, dass in Js-Objekte als Referenz übergeben werden. Dies bedeutet, dass alle an Ihrem Objekt vorgenommenen Änderungen auf Ihre obj.savedItem-Eigenschaft angewendet werden.

Fix: Speichern Sie einen tiefen Klon in obj.savedItem

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

cloneDeep ist ein lodash Methode, die meisten js Libs eines ihrer eigenen Versorgung, zum Beispiel jQuery's $.extend, etc.

Sie könnten leicht Ihre eigene tiefe Klonfunktion rollen, schauen Sie sich die Optionen auf diesem thread.

Ein komplettes Beispiel mit jQuery:

function SavedFeature() { 
    this.savedItem; 

    this.clone = function() { 
     return $.extend(true, {}, this); 
    }, 

    this.storeState = function() { 
     this.savedItem = this.clone(); 
    } 
} 

es auf diese Weise tun können Sie, indem Sie Ihre clone Methode an unterschiedliche Umgebungen anpassen, wie es die verwendete Bibliothek Methode facading.

+0

Scheint wie tiefes Kopieren die einzige Möglichkeit ist, dies für ein ganzes Objekt zu erledigen. – ThrowsException

1

Es gibt Dutzende Möglichkeiten, es zu implementieren. Ich werde nur einen einfachen tun. Eigenschaft speichern. Berücksichtigen Sie , wenn Sie das gesamte Objekt speichern möchten, müssen Sie eine tiefe Kopie des Objekts machen.

dies ist Ihre Funktion:

function SavedFeature() { 
     this.savedItem = {'isNew': true}; 
     this.stateMachine = new StateMachine(); 
} 

das eine Art Zustandsmaschine ist:

function StateMachine() { 
     var state = { 'isNew' : null}; 
     function set(newState) { 
     state.isNew = newState.isNew; 
     } 
     function get() { 
     return state.isNew; 
     } 
     return { 
     get : get, 
     set : set 
     }; 
    } 

die, wissen, wie isNew Eigenschaft speichern

und eine Arbeitsprobe:

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 

Sie können diesen Code anpassen und erreichen die Funktionalität, was Sie brauchen. hoffe, dass hilft

Verwandte Themen