2009-03-23 8 views
2

Variabler Bereich in JS verwirrend die Hölle aus mir heraus. Wenn ich im folgenden Code die public-Methode setClient verwende, um eine clientID zu setzen, kann ich mit der getClient-Methode auf den Wert innerhalb der track-Methode zugreifen. Ich kann jedoch auf diese Weise nicht auf den Wert der Version des privaten Mitglieds (oder eines anderen privaten Mitglieds) zugreifen. Ich hatte angenommen, daß var_this = eine Schließung irgendeiner Art erzeugen würde, die den Zugriff auf den Umfang der Container-Funktion erlaubt.JS Variable Scope

Und jetzt bin ich verwirrt. Mir ist klar, dass das wahrscheinlich sehr einfach ist, also dachte ich, ich würde hier fragen. Wo auf der Erde hat man das falsche Ende des Stockes gegriffen?

function Container() 
{ 
    // private members 
    var version = '0.1'; 
    var CID = false; 
    var _this = this; 

    // public members 
    this.getVersion = function() { return _this.version; } 
    this.getClient = function() { return _this.CID; } 
    this.setClient = function(CID) { _this.CID = CID; } 

    // private methods 
    this.getQS = function() { return _this.version; } 

    // public methods 
    this.track = function() 
    { 
     if (_this.CID) 
     { 
      var date = new Date(); 

      data = 
      { 
       cid: _this.getClient(), 
       sw: screen.width ? screen.width : false, 
       sh: screen.height ? screen.height : false, 
       d: date.getTime() 
      } 

      qs = ''; 

      for (p in data) { qs += p+'~'+data[p]+'-'; } 

      var elHd = document.getElementsByTagName("head")[0];   
      var elScr = document.createElement('script'); 

      elScr.type = 'text/javascript'; 
      elScr.src = 'http://example.org/'+qs+ 
          'version-'+_this.getVersion(); 

      elHd.appendChild(elScr); 
     } 
     else 
     { 
      alert('no client ID'); 
     } 
    } 
} 

Antwort

1

Machen Sie Ihren Container-Konstruktor ein bisschen besser. Die Versions- und CID-Variablen sind privat und befinden sich innerhalb des Container-Konstruktorbereichs. Sie benötigen daher nicht die Referenz für diesen Bereich, und sie würde überhaupt nicht funktionieren. Dies. Referenz wäre für öffentlich zugängliche Eigenschaften und Methoden erforderlich und äußerst nützlich, wenn Sie den Prototyp außerhalb der Konstruktorfunktion definieren, wie im zweiten Codeblock gezeigt.

function Container() { 
    var version = "0.1", CID = false; 

    this.getVersion = function()  { return version }; 
    this.getClient = function()  { return CID  }; 
    this.setClient = function(value) { CID = value }; 

    this.track = function() { 
    if (CID) { 
     var qs = "", data = { 
     cid: this.getClient(), 
     sw: screen.width ? screen.width: false, 
     sh: screen.height ? screen.height: false, 
     d: (new Date).getTime() 
     }; 
     for (var p in data) qs += p +"~"+ data[p] +"-"; 
     var js = document.createElement("script"); 
     js.type = "text/javascript"; 
     js.src = "http://example.org/"+ qs +"version-"+ this.getVersion(); 
     document.getElementsByTagName("head")[0].appendChild(js); 
    } else { 
     alert("No Client ID"); 
    } 
    }; 
}; 

dies. Referenz wird entscheidend, wenn Sie den Prototyp nach dem Konstruktor hinzufügen/überschreiben.

function Container2() { } 
Container2.prototype = { 
    CID: null, 
    version: "0.1", 
    track: function() { 
    alert(this.version); 
    } 
} 
+0

Vielen Dank. Ich arbeitete eindeutig unter dem falschen Eindruck, dass ich eine Art Schließung oder Rückverweis erstellen musste. Ich denke, es ist zurück zu den O'Reilly-Büchern für mich. – jthompson

+0

Kein Problem, es braucht ein bisschen, um deinen Kopf darum zu wickeln. Und wie in einem anderen Beitrag hier erwähnt, ist http://www.crockford.com/javascript/private.html eine gute Lektüre, um zu helfen, zu verfestigen, wie es funktioniert. –

0

Ich bin nicht sicher, ich bin zu verstehen, wo Sie verwirrt sind (oder, warum Sie tun Dinge, wie du bist, so dass ich kann Meta-verwechselt werden). Was passiert, wenn Sie gerade tun:

this.getVersion = function() { return version; } 
0

Die Variable Version kein Mitglied Bereich der Container-Klasse ist. Es ist eine lokale Variable, die nur für die Dauer des Container-Konstruktors existiert. Sie müssen es so erstellen (wie Sie mit den Methoden sind):

this.version = "0.1"; 

Sie sollten für die CID Feld das gleiche tun. Besser noch, füge sie dem Prototyp-Objekt deiner Klasse hinzu.

0

Die einfache Antwort ist

this.getVersion = function() { return version; } 

zu verwenden, da die JavaScript-Funktionen sind Verschlüsse der Verweis auf Version, eine lokale Variable in der obigen Funktion auch nach der Funktion zurück zugegriffen werden kann. Der Versuch, auf _this.version zuzugreifen ist ein Versuch, die Version Mitglied der _this Objekt zu lesen. Da Sie niemals _this eine Version Member zugewiesen haben, wird ein Wert von undefined zurückgegeben.

In Javascript, werden Sie nur in der Lage sein, Mitglieder zugreifen, die entweder explizit auf das Objekt mit dem Sie arbeiten hinzugefügt werden, oder auf das Objekt des Prototyps oder der Prototyp des Prototyps usw.

Mehr Informationen hinzugefügt auf die Verwendung von privaten Mitgliedern mit JavaScript kann in einem großen Artikel von Douglas Crockford gefunden werden: Private Members in JavaScript

Verwandte Themen