2009-02-26 5 views
3

Ich habe eine Javascript-Klasse, die ein paar Funktionen und Mitgliedsobjekte enthält:Korrekte Möglichkeit, ein Javascript-Objekt zurückzusetzen oder zu löschen?

function MyUtils() 
{ 
    // Member Variables (Constructor) 
    var x = getComplexData(); 
    var y = doSomeInitialization(); 

    // Objects 
    this.ParamHash = function() 
    { 
    // Member variables 
    this.length = 0; 
    this.items = new Array(); 

    // Constructor 
    for (var i = 0; i < arguments.length; i += 2) 
    { 
     // Fill the items array. 
     this.items[arguments[i]] = arguments[i+1]; 
     this.length++; 
    } 
    } 

    // Functions 
    this.doSomething = function() 
    { 
    // Do something. 
    // Uses the items in the ParamHash object. 
    for (var i in this.ParamHash.items) 
    { 
     // Really do something! 
    } 

    // Clear the ParamHash object -- How?? 
    } 
} 

Diese auf folgende Weise aufgerufen wird:

// First call - works fine. 
var utils = new MyUtils(); 
utils.paramHash = new utils.ParamHash("a", 1, "b", 2); 
utils.doSomething(); 

// Don't want to re-initialize. 
// utils = new MyUtils(); 

// Consequent call - crashes ["Object doesn't support this action."]. 
utils.paramHash = new utils.ParamHash("c", 3); 
utils.doSomething(); 

Das Problem der Einschränkung ergibt sich, dass ich die wiederverwendet werden soll Gleiches utils Objekt im gesamten Code, ohne es neu initialisieren zu müssen. Außerdem möchte ich, dass das ParamHash-Objekt jedes Mal neu erstellt wird, wenn ich es anrufe. Konsequente Aufrufe an den ParamHash-Konstruktor werfen jedoch einen Fehler "Objekt unterstützt diese Aktion nicht". In diesem Stadium kann ich sehen, dass das Objekt utils.paramHash immer noch die alten Werte ("a", "b") enthält.

Ich habe verschiedene Möglichkeiten ausprobiert, um das ParamHash-Objekt zu löschen, z. B. die Elemente und die Länge auf null zu setzen und Objekte aus dem Array zu entfernen. Nichts schien zu arbeiten, bis ich die folgende Art und Weise verwendet wird (in der doSomething()-Funktion):

this.paramHash.items = new Array(); 
this.paramHash.length = 0; 

Dies scheint falsch, weil was ist, wenn ich viel Membervariablen hatte ... hätte ich einzeln jeder von ihnen zurücksetzen? Also, die Frage ist: Was ist der beste Weg, um das ParamHash Objekt in den Ausgangszustand zurückzusetzen? Ich bin sicher, ich hoffe, dass es einen saubereren/direkteren Weg gibt. Etwas wie:

// Doesn't work! :-(
this.paramHash = new function() {}; 

EDIT: Ich bin für eine Cross-Browser-Lösung - eine, die atleast in IE6 + und FF 2+ arbeitet.


Lösung: Dank Cristoph, ich war in der Lage, es zu tun, indem eine separate Variable/Eigenschaft innerhalb MyUtils zu schaffen, die nur die Instanz der ParamHash Funktion hält.

function MyUtils() 
{ 
    // Same ol' stuff. 
    var myParamHash; 
} 

// First call - works fine. 
var utils = new MyUtils(); 
utils.myParamHash = new utils.ParamHash("a", 1, "b", 2); 
utils.doSomething(); 

// Consequent call - works fine now. 
utils.myParamHash = new utils.ParamHash("c", 3); 
utils.doSomething(); 
+0

ich eine einfachere Lösung zu meiner Antwort hinzugefügt; Ich weiß nicht, welches Problem du lösen willst, also könnte dein Code besser geeignet sein ... – Christoph

Antwort

3

Diese

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2); 

überschreibt die die Eigenschaft, die die ParamHash() -Konstruktorfunktion mit einem Instanz-Objekt hält. Sie könnten den Konstruktor zurück über

utils.ParamHash.constructor 

zu erhalten, aber der Reiniger Weg wäre, es nicht in erster Linie überschreibt und eine separate Eigenschaft verwenden, um die Instanz zu halten.


Ich weiß nicht, das genaue Problem Cerebrus zu lösen versucht, so könnte es gute Gründe für das, was er tut. Aber meiner Meinung nach ist seine Lösung übermäßig kompliziert. Ich würde so etwas tun:

function MyUtils() { 
    this.x = getComplexData(); 
    this.y = doSomeInitialization(); 
    this.params = {}; 
} 

MyUtils.prototype.doSomething = function() { 
    for(var prop in this.params) { 
     if(this.params.hasOwnProperty(prop)) { 
      // do stuff 
     } 
    } 
}; 

var utils = new MyUtils; 
utils.params = { a : 1, b : 2 }; 
utils.doSomething(); 

Die Prüfung auf hasOwnProperty() nicht erforderlich ist, wenn Sie sicher sein können, dass niemand mit Object.prototype verwirrt.


Einige zusätzliche Bemerkungen:

  • in JavaScript, in der Regel nur die Namen der Konstruktorfunktionen
  • items aktiviert werden, sollten nicht ein Array sein, aber ein einfaches Objekt, das heißt this.items = {};
+0

Können Sie ein Beispiel dafür bereitstellen, wie ich kann den abgerufenen Konstruktor (mit Hilfe der Konstruktoreigenschaft) verwenden, um das Objekt zurückzusetzen? – Cerebrus

+0

'utils.ParamHash = utils.ParamHash.constructor' macht die Zuweisung rückgängig, dh danach können Sie neue Werte über' utils.ParamHash = new utils zuweisen. ParamHash ("c", 3, "d", 4) ' – Christoph

+0

Vielen Dank. Ich habe meine Frage bearbeitet, um die endgültige Lösung, die ich verwendet habe. – Cerebrus

0

Haben Sie versucht, das neue Schlüsselwort wegzulassen?

utils.ParamHash = utils.ParamHash("c", 3); 
+0

Ich habe, obwohl ich überrascht gewesen wäre, wenn das geklappt hätte. Es sagt "Funktion erwartet." :-( – Cerebrus

+0

Wenn Sie das neue Schlüsselwort weglassen, erstellt es kein neues Objekt. Es führt nur die Konstruktorfunktion in einem globalen Kontext aus (Festlegen aller Eigenschaften auf das Fensterobjekt)! –

2

Wenn Sie dies taten

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2); 

Sie haben die ParamHash-Konstruktorfunktion durch eine Objektinstanz ersetzt. Nachfolgende new ParamHash() schlägt fehl, weil utils.ParamHash nicht mehr eine Konstruktorfunktion ist.

Try this:

var utils = new MyUtils(); 
utils.paramHashInstance = new utils.ParamHash("a", 1, "b", 2); 
utils.DoSomething(); 
+0

Danke, Chetan. Das wirft keinen Fehler, aber dann die Instanz oder die Parameter sind nicht verfügbar innerhalb der DoSomething() - Funktion, die Teil der Klasse ist Ich muss das Zurücksetzen von innerhalb der DoSomething() - Funktion durchführen – Cerebrus

+0

@Cerebrus: Warum ist die Instanz nicht verfügbar? 'for (var i in thi s.paramHashInstance.items) 'sollte gut funktionieren ... – Christoph

+0

Weil ich es versäumt habe, die Eigenschaft in der MyUtils-Klasse zu erstellen. Ich fügte die Eigenschaft dynamisch hinzu, wie @ Chetans Antwort zu sagen schien. Siehe meine bearbeitete Frage. – Cerebrus

Verwandte Themen