12 Stimmen

Javascript-Abschluss und Datensichtbarkeit

Ich versuche, meinen Kopf um die Idee der Klassen, Daten Sichtbarkeit und Schließungen (speziell in Javascript) zu wickeln, und ich bin auf der jQuery docs Seite für Typen, es erwähnt, dass Schließungen verwendet werden, um Daten zu verbergen:

Das Muster ermöglicht es Ihnen, Objekte mit Methoden zu erstellen, die mit Daten arbeiten, die für Außenstehende nicht sichtbar sind - die eigentliche Grundlage der objektorientierten Programmierung.

Das Beispiel:

function create() {
  var counter = 0;
  return {
    increment: function() {
      counter++;
    },
    print: function() {
      console.log(counter);
    }
  }
}
var c = create();
c.increment();
c.print(); // 1

Indem die Variable counter mit dem Schlüsselwort var deklariert wird, ist sie bereits innerhalb der Funktions-/Klassendefinition lokal skaliert. Soweit ich weiß, ist sie von außen zunächst nicht zugänglich. Übersehe ich etwas aus Sicht der Datensichtbarkeit?

Zweitens: Gibt es einen Vorteil, die Klasse wie oben zu schreiben und nicht wie unten:

function create() {
  var counter = 0;
  this.increment = function() {
      counter++;
  }
  this.print = function() {
      console.log(counter);
  }
  return this;
}
var c = create();
c.increment();
c.print(); // 1

Wie ich es verstehe, sind diese mehr oder weniger semantisch die gleiche Sache - die erste ist nur mehr "jQuery-Stil". Ich frage mich nur, ob es einen Vorteil oder eine andere Nuance gibt, die ich nicht vollständig aus dem ersten Beispiel zu schätzen weiß. Wenn ich richtig bin, erstellen beide Beispiele Schließungen in, dass sie Zugriff auf Daten außerhalb ihres eigenen Bereichs deklariert sind.

http://docs.jquery.com/Types#Closures

1voto

Steerpike Punkte 16009

Christian Heilmann hat einen recht anständigen Artikel über das Modulmuster die Sie beschrieben haben, die Ihnen helfen könnten, sich ein Bild davon zu machen und zu verstehen, warum es nützlich ist.

1voto

Matt Punkte 20778

Diese Syntax macht für mich mehr Sinn, wenn ich von einem OOP-Hintergrund komme:

Create = function {
  // Constructor info.

  // Instance variables
  this.count = 10;
}

Create.prototype = {

     // Class Methods
     sayHello : function() {
          return "Hello!";
     },

     incrementAndPrint : function() {
          this.count++;

          // Inner method call.
          this.print();
     },

     print : function() {
         return this.count;
     }

}

var c = new Create();
alert(c.incrementAndPrint());

1voto

chris Punkte 11
MYAPP = (function(){
   var v1,v2;
   return {
    method1:function(){},
    method2:function(){}
   };
})();

Ich benutze immer Schließungen wie diese in meiner Anwendung, wie dies zu tun, sind alle meine eigenen definierten Methoden in MYAPP Namespace, die v1 und v2 sind nur zugänglich durch Methoden in MYAPP.In meiner Anwendung, schreibe ich oft nur eine "app.js"-Datei, alle meine js-Codes in. Ich denke, Sie können eine Methode namens "registy" definieren, um private Variablen in MYAPP zu definieren, die Sie dann in Ihren Methoden verwenden können. Alle zusätzlichen Variablen und Methoden sollten durch die registy-Methode definiert werden, wenn Sie zusätzliche Codes in der HTML-Datei hinzufügen möchten, genau wie die JQuery.extend-Methode. Ich habe gehört, wenn man zu viele Closures im IE-Browser verwendet, kann es leicht zu einem Stack Overflow kommen. (Meiner Meinung nach)

0voto

Miles Punkte 29684

In Ihrem zweiten Beispiel, wenn Sie create() im Rahmen der Funktion, this ist das globale Objekt (was immer der Fall ist, wenn Sie eine "bloße" Funktion aufrufen, ohne sie als Konstruktor zu verwenden oder auf sie als Eigenschaft zuzugreifen (z. B. bei einem "Methoden"-Aufruf)). In Browsern ist das globale Objekt window . Wenn Sie also in der Folgezeit create aufrufen, werden neue Closures erstellt, aber Sie weisen sie dann demselben globalen Objekt zu wie zuvor und überschreiben die alten Funktionen, was nicht erwünscht ist:

var c = create(); // c === window
c.increment();
c.print(); // 1
var c2 = create(); // c2 === c === window
c.print(); // 0
c2.print(); // 0
increment(); // called on the global object
c.print(); // 1 
c2.print(); // 1

Wie bereits von anderen erwähnt, besteht die Lösung darin, Folgendes zu verwenden new create() .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X