gruss Siri,
Beide Schreibweisen erlauben die Deklaration von privaten und öffentlichen
Variablen/Methoden. Wo liegt der Unterschied? ...
...
Variante A ist eine Konstruktorfunktion, die über den [new] Operator und den
den Bezug auf [this] Instanzen ihres eigenen Typs erstellt.
(new Konstruktor1) instanceof Konstruktor1
ist in jedem Fall wahr.
...
Variante A:
function Konstruktor1 () {
//privat
k1var1 = "test1";
/*
ganz böse ... die Zuweisung von "test1" auf [k1var1] erfolgt im globalen Namensraum.
Nur ein vorangestelltes [var] zwingt [k1var1] in den lokalen Scope der Funktion [Konstruktor1].
/
//local
var k1var1 = "test1";
/
Kapselung wird durch den lokalen Scope der Variable und dem Aufruf von [Konstruktor1] erreicht.
Siehe dazu molilys Erläuterungen zu [Closure]s.
*/
// öffentlich
this.k1var2 = "test2";
/*
Richtig. [this] bindet die Eigenschaft [k1var2] direkt adressierbar an jede Instanz der
Konstruktor-Funktion [Konstruktor1].
*/
//privat
k1methode1 = function() {
alert (k1var1+"-"+this.k1var2);
}
/*
nein - keineswegs privat, sondern global - siehe Erklärung weiter oben und Korrektur direkt darunter.
*/
var k1methode1 = function() {
alert (k1var1+"-"+this.k1var2);
}
//öffentlich
this.k1methode2 = function() {
alert (k1var1+"-"+this.k1var2);
}
/*
jo.
*/
}
var instanz1 = new Konstuktor1();
instanz1.k1methode2(); // geht
/*
jepp
*/
instanz1.k1methode1(); // geht nicht
/*
richtig - [k1methode1] wurde ja auch im globalen Namensraum angelegt
/
window.k1methode1();
/
... sollte aufrufbar sein und "test1-undefined" liefern ...
... warum? ...
- [k1var1] wurde ebenfall global angelegt und lässt sich nach "test1" auflösen.
- [k1var2] hingegen existiert nicht im globalen namensraum, ...
- ... denn genau dorthin wird [this.k1var2] aus der global angelegten [k1methode1] aufgelöst.
*/
> ...
Die Methode [Konstruktor2] ist keine Konstruktor-Funktion, obwohl der gemeinsame Aufruf von
[new] Operator und [Konstruktor2] aus dem Beispiel der Variante B dies so erscheinen läßt.
`(new Konstruktor2) instanceof Konstruktor2`{:.language-javascript} wird niemals wahr sein.
Warum?
[Konstruktor2] gibt ein durch ein Objekt-Literal erzeugtes Objekt zurück. Dieses Objekt ist
somit keine Instanz von [Konstruktor2]. Als einzige Eigenschaft besitzt dieses Objekt die
Methode [k2methode2], die nur deshalb Zugriff auf die im lokalen Funktions-Scope von [Konstruktor2]
vereinbarte Variable [k2var1] hat, da das zurückgegebene Objekt im selben Scope erzeugt wird.
Siehe dazu wiederum molilys Erläuterungen zu [Closure]s.
> ...
> Variante B:
> ~~~javascript
function Konstruktor2 () {
>
> //privat
> var k2var1 = "test3";
/*
jepp - aber trotzdem bitte "lokal" statt "privat" denken und schreiben.
*/
> // öffentlich
> k2var2 = "test4";
/*
nope - [k2var2] liegt im globalen Namensraum - siehe Erläuterungen zu Beispiel A.
*/
>
> //privat
> function k2methode1() {
> alert (k2var1);
> }
/*
jepp
*/
> //öffentlich
> return {
> k2methode2: function() {
> alert (k2var1);
> }
> }
/*
siehe Erklärung zu Beispiel B.
*/
> }
> var instanz2 = new Konstuktor2();
> instanz2.k2methode2(); // geht
/*
aber nur wegen [link:http://molily.de/js/organisation-module.html#revealing-module@title=Revealing Module Pattern]
*/
> instanz2.k2methode1(); // geht nicht
/*
richtig - [k2methode1] wurde ja auch im globalen Namensraum angelegt
*/
> ...
... Ist es eine Frage des persönlichen Stils? Oder gibt es bestimmte Einsatzzwecke für die eine
der Varianten besser geeignet ist als die andere?
Benutze Konstruktoren, wenn Du ein Typsystem erstellen möchtest, wo Du die Herkunft von Objekten
anhand des [instanceof] Operators bestimmen möchtest. bzw. wenn Deinen Objekten Methoden über die
Delegation durch [Constructor.prototype] zugewiesen werden sollen.
so long - peterS. - pseliger@gmx.net
»Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]