Interne public static member nicht aufrufbar
felix12
- javascript
Kann mir mal jemand erklären, warum die public static variable "hallo" nicht aufgerufen werden kann?? Erst wenn ich eine Instanz der Klasse bilde kann die variable gelesen werden... das macht aber 0 Sinn da eine statische Klassenvariable ohne instanz lesbar sein müsste!?!
<html>
<head>
</head>
<body>
<script type="text/javascript">
function SomeClass() {
SomeClass.hallo = "hallo";
}
//new SomeClass();
alert(SomeClass.hallo);
</script>
</body>
</html>
Die statische variable soll umbedingt innerhalb der Klasse deklariert werden, also nicht so:
function SomeClass() {
}
SomeClass.hallo = "hallo";
alert(SomeClass.hallo);
Hat jemand ne Idee?
Hi,
Kann mir mal jemand erklären, warum die public static variable "hallo" nicht aufgerufen werden kann?? Erst wenn ich eine Instanz der Klasse bilde kann die variable gelesen werden...
nö. Du musst lediglich die Funktion aufrufen, nicht unbedingt instanzieeren.
das macht aber 0 Sinn da eine statische Klassenvariable ohne instanz lesbar sein müsste!?!
Das macht 100 Sinn, da JavaScript-Code nicht willkürlich ausgeführt wird, nur weil es sein könnte, dass sich jemand drüber freut.
function SomeClass() {
Hier wird eine Funktion erzeugt.
SomeClass.hallo = "hallo";
Sofern jemand diese aufruft, wird dieser Code ausgeführt.
Die statische variable soll umbedingt innerhalb der Klasse deklariert werden,
Warum?
Cheatah
nö. Du musst lediglich die Funktion aufrufen, nicht unbedingt instanzieeren.
Das macht 100 Sinn, da JavaScript-Code nicht willkürlich ausgeführt wird, nur weil es sein könnte, dass sich jemand drüber freut.
Ehm ja aber warum klappt dann das Beispiel nicht.
Die statische variable soll umbedingt innerhalb der Klasse deklariert werden,
Warum?
weil sie auf andere interne functionen und variablen zurückgreifen muss die ich nicht über prototypen ereichen könnte. Aber das steht hier nicht zur debatte!
Ciao Felix
Hi,
nö. Du musst lediglich die Funktion aufrufen, nicht unbedingt instanzieeren.
Das macht 100 Sinn, da JavaScript-Code nicht willkürlich ausgeführt wird, nur weil es sein könnte, dass sich jemand drüber freut.
Ehm ja aber warum klappt dann das Beispiel nicht.
weil der Code nicht ausgeführt wurde. Nichts und niemand hat Deiner Funktion eine hallo-Eigenschaft gegeben.
Die statische variable soll umbedingt innerhalb der Klasse deklariert werden,
Warum?
weil sie auf andere interne functionen und variablen zurückgreifen muss die ich nicht über prototypen ereichen könnte.
Das beantwortet nicht die Frage.
Aber das steht hier nicht zur debatte!
Natürlich tut es das. Hier steht *alles* zur Debatte.
Cheatah
weil der Code nicht ausgeführt wurde. Nichts und niemand hat Deiner Funktion eine hallo-Eigenschaft gegeben.
function SomeClass() {
SomeClass.hallo = "hallo"; <- und was ist das?
}
Die statische variable soll umbedingt innerhalb der Klasse deklariert werden,
Warum?
weil sie auf andere interne functionen und variablen zurückgreifen muss die ich nicht über prototypen ereichen könnte.Das beantwortet nicht die Frage.
Doch ich will, eine statische öffentliche klassen funktion haben, die auf interne private statische (instanz) variablen zugreift. Diese könnte ich nicht mit dem hinzufügen der function über prototype erreichen!
Aber das steht hier nicht zur debatte!
Natürlich tut es das. Hier steht *alles* zur Debatte.
Kannst du mir nicht kurz mit einem code beispiel erläutern wie ich das deiner meinung nach machen sollte, bzw an welcher stelle genau mein beispiel deiner meinung nach falsch ist? In Java kann ich sofort auf eine statische Variable zugreifen, ohne irgendwelche umwege.
felix
Hi,
weil der Code nicht ausgeführt wurde. Nichts und niemand hat Deiner Funktion eine hallo-Eigenschaft gegeben.
function SomeClass() {
SomeClass.hallo = "hallo"; <- und was ist das?
}
Das geschieht, sobald die Funktion aufgerufen wird. Wird sie aber im von Dir gegebenen Beispielcode nicht.
cu,
Andreas
Das geschieht, sobald die Funktion aufgerufen wird. Wird sie aber im von Dir gegebenen Beispielcode nicht.
Jo das hatte ich mittlerweile begriffen, es irritiert mich nur das bei javascript erst die funktion aufgerufen worden sein muss, bevor man auf die variablen, so wie sie bei mir deklariert sind, zugreifen kann.
...In java geht der zugriff auf statische variablen direkt über die Klasse ohne irgendeinen vorherigen aufruf aber da hat mir kai schon gesagt "Vergiß alles, was für Java gilt" :)
Gruß Felix
...In java geht der zugriff auf statische variablen direkt über die Klasse ohne irgendeinen vorherigen aufruf aber da hat mir kai schon gesagt "Vergiß alles, was für Java gilt" :)
Wieso? das gilt genauso für JS.
function SomeClass(){}
SomeClass.hallo = "hallo";
Die statische Variabel hallo ist vorhanden ohne Aufruf.
Was du willst ist eine private statische Variabel, ich weiß nicht ob es sowas in Java gibt, in JS kann man sowas konstruieren.
Mein anderes Beispiel war falsch. Da mir nich klar ist, wozu du sowas brauchst, hatte ich heute morgen Schwierigkeiten beim umsetzen deiner Gedanken. Du willst Zugriff auf ein statische private Variabel über eine statische Funktion, richtig?
Also:
(function() {
var privat = 'hallo';
window.SomeClass = function (){}
SomeClass.hallo = function() { return privat; };
})();
Struppi.
Hallo Struppi!
> (function() {
^
> var privat = 'hallo';
> window.SomeClass = function (){}
> SomeClass.hallo = function() { return privat; };
> })();
^
Ich verstehe diese Schreibweise nicht. Warum die Klammerpaare, die ich markiert habe?
Viele Grüße aus Frankfurt/Main,
Patrick
gruss Patrick;
...
Ich verstehe diese Schreibweise nicht. Warum die Klammerpaare, die ich markiert habe?
...
(function() {/*
^
hier wird einfach ein (anonymes) funktionsobjekt (function expression)
*/
var privat = 'hallo';
window.SomeClass = function (){}
SomeClass.hallo = function() { return privat; };
})();/*
^
in klammern eingeschlossen und nach der initialisierung sofort ueber
den call operator »()« ausgefuehrt.
die das funktionsobjekt umschliessenden klammern sind notwendig, um
den code auch dann noch fehlerfrei durchlaufen zu lassen, wenn ein
sogenannter *minifier* oder *crunchinator* den gesamten JavaScript-
code auf eine zeile zusammengedrueckt haben sollte.
*/
so long - peterS. - pseliger@gmx.net
Hallo Peter!
(function() {/*
^
hier wird einfach ein (anonymes) funktionsobjekt (function expression)
*/
})();/*
^
in klammern eingeschlossen und nach der initialisierung sofort ueber
den call operator »()« ausgefuehrt.die das funktionsobjekt umschliessenden klammern sind notwendig, um
den code auch dann noch fehlerfrei durchlaufen zu lassen, wenn ein
sogenannter *minifier* oder *crunchinator* den gesamten JavaScript-
code auf eine zeile zusammengedrueckt haben sollte.
*/
Ah, danke. Ich hatte das öfters in einigen von Struppis Beispiele hier gesehen und wollte schon länger fragen!
Viele Grüße aus Frankfurt/Main,
Patrick
(function() {/*
^
hier wird einfach ein (anonymes) funktionsobjekt (function expression)
*/
var privat = 'hallo';
window.SomeClass = function (){}
SomeClass.hallo = function() { return privat; };
})();/*
^
in klammern eingeschlossen und nach der initialisierung sofort ueber
den call operator »()« ausgefuehrt.
Hmmm da hast du mir schon wieder eine interessante Sache beigebracht! Vielen Dank. Ich hätte nie gedacht das eine Funktion nur über den Aufruf des Bezeichners von alleine gestartet werden kann... :)
Freundliche Grüße
Felix
gruss Struppi, hallo felix12,
...
Was du willst ist eine private statische Variabel, ich weiß nicht,
ob es sowas in Java gibt, in JS kann man sowas konstruieren.... Du willst Zugriff auf ein statische private Variabel über eine
statische Funktion, richtig?Also:
(function() {
var privat = 'hallo';
window.SomeClass = function (){}
SomeClass.hallo = function() { return privat; };
})();
wobei ich auch aus aesthetisch gruenden den zur \*klasse\* hin- oder
besser zum \*private static\* wrapper umgebogenen anonymen funktions-
stack zusammen mit dem konstruktor so abhandeln wuerde, dass es nicht
mehr noetig ist, diesen (den konstruktor) ueber [window] zu adressieren:
~~~javascript
var SomeConstructor = (function () { // kind of *private static* wrapper function
var hallo = "hallo";
var cnstr = (function () {/*
code */
});
cnstr.getHallo = (function () {
return hallo;
});
return cnstr;
})();
var obj = new SomeConstructor();
alert(obj.hallo); // [undefined]
alert(obj.getHallo); // [undefined]
alert(SomeConstructor.getHallo()); // "hallo"
/*
copy und paste nach : [[link:http://jconsole.com/]]
*/
@ alle:
gaebe es darueber hinaus noch eine allgemeine unterstuetzung von
[__defineSetter__] bzw. [__defineGetter__], waere es ein leichtes,
auch noch konstanten, wie z.b. bei [Math] existierend, umzusetzen:
var OtherConstructor = (function () { // kind of *private static* wrapper function
var hallo = "hallo";
var cnstr = (function () {/*
code */
});
cnstr.__defineGetter__("HALLO", (function () { // gecko only
return hallo;
}));
return cnstr;
})();
var obj = new OtherConstructor();
alert(obj.hallo); // [undefined]
alert(obj.HALLO); // [undefined]
alert(OtherConstructor.HALLO); // "hallo"
/*
copy und paste nach : [[link:http://jconsole.com/]]
*/
so long - peterS. - pseliger@gmx.net
Was du willst ist eine private statische Variabel, ich weiß nicht ob es sowas in Java gibt, in JS kann man sowas konstruieren.
Doch das gibt es in Java natürlich auch :)
Mein anderes Beispiel war falsch. Da mir nich klar ist, wozu du sowas brauchst, hatte ich heute morgen Schwierigkeiten beim umsetzen deiner Gedanken. Du willst Zugriff auf ein statische private Variabel über eine statische Funktion, richtig?
Also:
(function() {
var privat = 'hallo';
window.SomeClass = function (){}
SomeClass.hallo = function() { return privat; };
})();
>
> Struppi.
Danke Struppi, genau sowas habe ich gebraucht wobei die Lösung von von Peter ein bisschen eleganter ist :)
> wobei ich auch aus aesthetisch gruenden den zur \*klasse\* hin- oder
> besser zum \*private static\* wrapper umgebogenen anonymen funktions-
> stack zusammen mit dem konstruktor so abhandeln wuerde, dass es nicht
> mehr noetig ist, diesen (den konstruktor) ueber [window] zu adressieren:
> ~~~javascript
var SomeConstructor = (function () { // kind of *private static* wrapper function
>
> var hallo = "hallo";
>
> var cnstr = (function () {/*
>
> code */
>
> });
> cnstr.getHallo = (function () {
>
> return hallo;
> });
>
> return cnstr;
>
> })();
>
> var obj = new SomeConstructor();
> alert(obj.hallo); // [undefined]
> alert(obj.getHallo); // [undefined]
> alert(SomeConstructor.getHallo()); // "hallo"
> /*
> copy und paste nach : [[link:http://jconsole.com/]]
> */
Auf sowas wäre ich im Leben nicht gekommen :) Das ist ziemlich genial ! Ehrlich! Trotzdem bin ich mit Javascript ein wenig auf Kriegsfuß weil die OO Umsetzungen ganz anders sind als ich sie aus Java kenne, aber ich hoffe ich werde in diesem Gebiet noch bewanderter :) Ich bin ja noch Jung:)
@ Struppi, Peter - also vielen Dank für eure Hilfe!
Danke Struppi, genau sowas habe ich gebraucht wobei die Lösung von von Peter ein bisschen eleganter ist :)
Naja, sie vermeidet, wie Peter schon sagt, aus ästhetischen Gründen window und führt dafür eine zusätzliche Funktion, ausserdem entspricht das nicht deinen Anforderungen, du kanst auf die statische Variabel erst _nach_ dem du ein Objekt konstruiert hast zugreifen. Und soweit ich dich verstanden habe wolltest du ohne den Konstruktor aufzurufen auf diese zugreifen und jetzt auf einmal ist es doch egal ob der Konstruktor aufgerufen wird?
Auf sowas wäre ich im Leben nicht gekommen :) Das ist ziemlich genial !
Irgendwie seltsam, das entspricht nicht dem was du wolltest.
Struppi.
Danke Struppi, genau sowas habe ich gebraucht wobei die Lösung von von Peter ein bisschen eleganter ist :)
Naja, sie vermeidet, wie Peter schon sagt, aus ästhetischen Gründen window und führt dafür eine zusätzliche Funktion, ausserdem entspricht das nicht deinen Anforderungen, du kanst auf die statische Variabel erst _nach_ dem du ein Objekt konstruiert hast zugreifen. Und soweit ich dich verstanden habe wolltest du ohne den Konstruktor aufzurufen auf diese zugreifen und jetzt auf einmal ist es doch egal ob der Konstruktor aufgerufen wird?
Auf sowas wäre ich im Leben nicht gekommen :) Das ist ziemlich genial !
Irgendwie seltsam, das entspricht nicht dem was du wolltest.
Struppi.
Hallo Struppi!
Ja da hast du recht deine Lösung entspricht dem, was mir ursprünglich am Herzen Lag, :) und ich bin dir auch sehr dankbar für deine Hilfe, denn ich bin dadurch ein ganzes Stück weiter gekommen :)
Aber ich interpretiere Peters Beispiel so, das eine Wrapper Funktion die eigentliche Haupt-Klasse (in seinem beispiel cnstr) kapselt und diese Hauptklasse auch nicht instanziert wird! Nur die Wrapper Klasse wird instanziert! :)
Felix
gruss felix12,
Irgendwie seltsam, das entspricht nicht dem was du wolltest.
Struppi.
Hallo Struppi!
Ja da hast du recht deine Lösung entspricht dem, was mir ursprünglich
am Herzen Lag, :) und ich bin dir auch sehr dankbar für deine Hilfe,
denn ich bin dadurch ein ganzes Stück weiter gekommen :)Aber ich interpretiere Peters Beispiel so, das eine Wrapper Funktion
die eigentliche Haupt-Klasse (in seinem beispiel cnstr) kapselt und
diese Hauptklasse auch nicht instanziert wird! Nur die Wrapper Klasse
wird instanziert! :)
wiederholung des beispielcodes:
var SomeConstructor = (function () { // kind of *private static* wrapper function
var hallo = "hallo";
var cnstr = (function () {/*
code */
});
cnstr.getHallo = (function () {
return hallo;
});
return cnstr;
})();
var obj = new SomeConstructor();
alert(obj.hallo); // [undefined]
alert(obj.getHallo); // [undefined]
alert(SomeConstructor.getHallo()); // "hallo"
/*
copy und paste nach : [[link:http://jconsole.com/]]
*/
... die eigentliche Haupt-Klasse (in seinem beispiel cnstr) ... ««
[cnstr] ist eine konstruktor-funktion. JavaScript ist klassenlos!
... und diese ... auch nicht instanziert wird! ... ««
[cnstr] wird tatsaechlich noch nicht instanziiert, dieser konstruktor
wird vom umschliessenden anonymen funktionsobjekt (dem wrapper) an die
variable [SomeConstructor] zurueckgegeben
... Nur die Wrapper Klasse wird instanziert! :) ... ««
nein - die einzige stelle, an der im beispiel ueberhaupt irgendwas
instanziiert wird, sieht so aus: var obj = new SomeConstructor();
das anonyme, den konstruktor umschliessende funktionsobjekt (der wrapper)
wird in einem ritt initialisiert und aufgerufen. der rueckgabewert dieser
funktion ist ein weiteres funktionsobjekt - der konstruktor, welcher dann
schlussendlich auf [SomeConstructor] abgebildet wird.
warum nun »SomeConstructor.getHallo
« als *public static* methode zugriff
auf das *private static* [hallo] hat, werde ich sofort und nur indirekt
in einem kurzen abriss des sprachkonzepts erlaeutern:
in JavaScript ist alles objekt ausser den primitiven werten [undefined]
und [null] sowie [string], [number] und [boolean]. auch funktionen sind
objekte. zusaetzlich zur ueblichen name/wert struktur, speichern diese
adressraeume anweisungen, die explizit durch anwendung einer der zwei
call-methoden [call] bzw. [apply] oder aber ueber den aufruf des call-
operators »()« ausgefuehrt werden.
darueber hinaus unterstuetzt JavaScript rekursion und gegenseitige
rekursion, sowie weitere paradigmen der funktionalen programmierung.
mit dieser ausrichtung des sprachkonzepts wird JavaScript zu einer
multiparadigmensprache, in der es sich sowohl rein prozedural - durch
rueckgabewertfreie funktionen, die ausschliesslich auf globalen
variablen arbeiten - programmieren laesst, als auch streng funktional
bzw. in allen moeglichen schattierungen dazwischen. den anforderungen
an objektorientierte sprachen wird JavaScript dadurch gerecht, dass
z.b. datenkapselung auf eine dem funktionalen programmierkonzept
zueigene weise stattfindet:
funktionen in JavaScript manifestieren sich im programmspeicher als
eigene adressraeume. gaengige deutsche bezeichnungen, um etwas ueber
die hardware-relevante arbeitsweise in erfahrung zu bringen, waeren
»unterprogramm« und »stapelspeicher«. im englischen gibt es die meiner
meinung nach eingaengigeren begriffe »call stack« bzw. »function stack«.
salopp umschrieben:
die lokalen variablen einer funktion sind von ausserhalb dieses sie
einschliessenden adressraumes nicht adressierbar. werden funktionen
nur geschickt genug verschachtelt, koennen sich deren lokale variablen,
obwohl von aussen immer noch nicht zugaenglich, trotzdem durch die
adressraeume hindurch referenzieren. und ... solange referenzen von
noch *lebenden* objekten in eine eigentlich schon abgearbeitete
funktion hinein bestehen, wird diese nicht von der automatischen
speicherbereinigung (garbage collection) erfasst.
instanzen eines bestimmten objekttyps werden ueber den gemeinsamen
aufruf von »new« operator und konstruktorfunktion erzeugt. innerhalb
eines konstruktors zeigt der operator »this« (wenn vorhanden) dabei
auf die oeffentlichen eigenschaften der erzeugten objektinstanz.
zu objektinstanzen und datenkapselung kaeme dann noch die vererbung,
welche in JavaScript in jedem fall durch delegation geschieht. schon
die ueber [[Function]] referenzierten methoden [apply] und [call]
ermoeglichen es einem objekt, die methoden eines anderen objekts zu
*borgen* und im eigenen kontext auszufuehren, ohne diese methoden
selbst besitzen zu muessen.
der [prototype] eines jeden konstruktors und die ueber ihn
referenzierbaren eigenschaften und methoden erweitern und
verfeinern nur das gerade angesprochene delegationskonzept.
in JavaScript waere man deshalb geradezu dazu verpflichtet,
objektkomposition auf basis wohldefinierter schnittstellen
als nativen - weil durch das sprachkonzept vorgegebenen -
vererbungsmechanismus direkt einzusetzen, statt zu versuchen,
klassenvererbung auf den gerade genannten grundlagen zu emulieren.
(
- siehe Gamma, Helm, Johnson, Vlissides ["Gang of Four"] :
"Entwurfsmuster - Elemente wiederverwendbarer objektorientierter
Software", S. 23 ff "Klassen- versus Schnittstellenvererbung" -
deutsche uebersetzung des amerikanischen orginals "Desig Patterns:
Elements of Reusable Object-Oriented Software"
- siehe auch: »JavaScript - Die am häufigsten mißverstandene Programmiersprache der Welt«
)
auch *klassen*-basierte mehrfachvererbung laesst sich in
JavaScript relativ unkompliziert nachbauen.
so long - peterS. - pseliger@gmx.net
Hallo Peter!
... die eigentliche Haupt-Klasse (in seinem beispiel cnstr) ... ««
[cnstr] ist eine konstruktor-funktion. JavaScript ist klassenlos!
Ja, für mich steht ein Konstruktor als synonym für eine klasse. Wie könnte ich sonst Konkrete Objekte (per "new") erzeugen ohne eine art "Klasse". :)
... Nur die Wrapper Klasse wird instanziert! :) ... ««
nein - die einzige stelle, an der im beispiel ueberhaupt irgendwas
instanziiert wird, sieht so aus:var obj = new SomeConstructor();
das anonyme, den konstruktor umschliessende funktionsobjekt (der wrapper)
wird in einem ritt initialisiert und aufgerufen. der rueckgabewert dieser
funktion ist ein weiteres funktionsobjekt - der konstruktor, welcher dann
schlussendlich auf [SomeConstructor] abgebildet wird.
hmm ja da habe ich "aufrufen" mit "instanzieren" rein namentlich verwechselt. :) Das kam weil ich die Bedeutung des Call-Operators mit der call()-methode verwechselt hatte, welche ja ein neues objekt "konstruiert", wobei der operator nur "aufruft". Das war aber nicht so von mir gemeint... uups :)
die lokalen variablen einer funktion sind von ausserhalb dieses sie
einschliessenden adressraumes nicht adressierbar. werden funktionen
nur geschickt genug verschachtelt, koennen sich deren lokale variablen,
obwohl von aussen immer noch nicht zugaenglich, trotzdem durch die
adressraeume hindurch referenzieren. und ... solange referenzen von
noch *lebenden* objekten in eine eigentlich schon abgearbeitete
funktion hinein bestehen, wird diese nicht von der automatischen
speicherbereinigung (garbage collection) erfasst.
Also kann man durch kaskadieren von funktionen verschiedene Sichtbarkeitsbenen von variablen erzeugen, die sich durch referenzieren zum teil umgehen lassen...
die ueber [[Function]] referenzierten methoden [apply] und [call]
ermoeglichen es einem objekt, die methoden eines anderen objekts zu
*borgen* und im eigenen kontext auszufuehren, ohne diese methoden
selbst besitzen zu muessen.
angenommen ich arbeite mit call, und ich überschreibe eine Funktion der "Klasse" die ich über call konstruiere, wie kann ich dann noch auf sie zugreifen? zb:
function SuperCat() {
this.sound = "miaow";
}
function SubCat() {
SuperCat.call(this);
var instance = this;
this.sound ="overridden miaow";
this.makesound = function() {
alert("the cat says" + instance.sound);
}
}
var felixcat = new SubCat();
felixcat.makesound();
wie rufe ich den member "sound" von der mit call erzeugten instanz der "Klasse" SuperCat auf? Ich meine wie referenziere ich diesen? geht das überhaupt?
in JavaScript waere man deshalb geradezu dazu verpflichtet,
objektkomposition auf basis wohldefinierter schnittstellen
als nativen - weil durch das sprachkonzept vorgegebenen -
vererbungsmechanismus direkt einzusetzen, statt zu versuchen,
klassenvererbung auf den gerade genannten grundlagen zu emulieren.
Naja damit muss ich mich noch anfreunden...
Danke für deine Mühe Peter!
Schöne Grüße
Felix
Nachtrag:
angenommen ich arbeite mit call, und ich überschreibe eine Funktion der "Klasse" die ich über call konstruiere, wie kann ich dann noch auf sie zugreifen? zb:
function SuperCat() {
this.sound = "miaow";
}function SubCat() {
SuperCat.call(this);
var instance = this;
this.sound ="overridden miaow";this.makesound = function() {
alert("the cat says" + instance.sound);
}
}var felixcat = new SubCat();
felixcat.makesound();wie rufe ich den member "sound" von der mit call erzeugten instanz der "Klasse" SuperCat auf? Ich meine wie referenziere ich diesen? geht das überhaupt?
Ich meine natürlich wie referenziere ich diesen aus SubCat heaus. Also, anstatt "alert("the cat says" + INSTANCE.sound);", sowas wie alert("the cat says" + SUPERCATINSTANCE.sound); //so das "miaow" herauskommt :)
Gruß Felix
hmm ja da habe ich "aufrufen" mit "instanzieren" rein namentlich verwechselt. :) Das kam weil ich die Bedeutung des Call-Operators mit der call()-methode verwechselt hatte, welche ja ein neues objekt "konstruiert",
Die call Mehode konstruiert nichts, sie ruft nur eine Funktion im Kontext auf.
angenommen ich arbeite mit call, und ich überschreibe eine Funktion der "Klasse" die ich über call konstruiere, wie kann ich dann noch auf sie zugreifen? zb:
function SuperCat() {
this.sound = "miaow";
}function SubCat() {
SuperCat.call(this);
Hier wird nichts konstruiert, du rufst SuperCat im Kontext von this auf, d.h. die Eigenschaft Sound wird einfach hinzugefügt.
Deutlicher wird das wenn du eine SuperCat Prototpye Funktion gibst, diese ist in SubCat nicht bekannt.
wie rufe ich den member "sound" von der mit call erzeugten instanz der "Klasse" SuperCat auf? Ich meine wie referenziere ich diesen? geht das überhaupt?
Nein, das geht nicht. Mal abgesehen von dem was du sowieso falsch machst, in JS werden überladene Funktion einfach überschrieben.
Mit Mozillabrowser hast du über _proto_ Zugriff auf das Orginal - im IE weiß ich nicht.
Struppi.
Die call Mehode konstruiert nichts, sie ruft nur eine Funktion im Kontext auf.
angenommen ich arbeite mit call, und ich überschreibe eine Funktion der "Klasse" die ich über call konstruiere, wie kann ich dann noch auf sie zugreifen? zb:
function SuperCat() {
this.sound = "miaow";
}function SubCat() {
SuperCat.call(this);Hier wird nichts konstruiert, du rufst SuperCat im Kontext von this auf, d.h. die Eigenschaft Sound wird einfach hinzugefügt.
Deutlicher wird das wenn du eine SuperCat Prototpye Funktion gibst, diese ist in SubCat nicht bekannt.
Achso, ok! :) Ich hatte mir ein tutorial zu call durchgelesen (http://www.webreference.com/js/column26/call.html) und da wohl den teil "[...] This capability enables you to do a multi-method object construction" falsch interpretiert. naja..
wie rufe ich den member "sound" von der mit call erzeugten instanz der "Klasse" SuperCat auf? Ich meine wie referenziere ich diesen? geht das überhaupt?
Nein, das geht nicht. Mal abgesehen von dem was du sowieso falsch machst, in JS werden überladene Funktion einfach überschrieben.
Mit Mozillabrowser hast du über _proto_ Zugriff auf das Orginal - im IE weiß ich nicht.
Danke für die Info!
Felix
hallo again Felix,
bitte entschuldige die lange wartezeit - ich bin gerade vielbeschaeftigt.
... die eigentliche Haupt-Klasse (in seinem beispiel cnstr) ... ««
[cnstr] ist eine konstruktor-funktion. JavaScript ist klassenlos!
Ja, für mich steht ein Konstruktor als synonym für eine klasse.
trenn Dich im kontext von JavaScript von dieser *denke*.
Wie könnte ich sonst Konkrete Objekte (per "new") erzeugen ohne
eine art "Klasse". :)
auch in klassenbasierte oo benoetigst Du dazu nur den konstruktor ;-)
...Das kam weil ich die Bedeutung des Call-Operators mit der call()-
methode verwechselt hatte, welche ja ein neues objekt "konstruiert",
wobei der operator nur "aufruft" ...
noe ... call-operator »()« und die call methoden »apply« und »call«
haben grundsaetzlich erstmal die gleiche aufgabe, naemlich ein
funktionsobjekt auszufuehren. ueber die beiden call-methoden lassen
sich ausserdem noch auf unterschiedlich flexible weise argumente an
eine funktion verbacken. darueber hinaus, und das ist der bei weitem
wichtigste aspekt, laesst sich der kontext, in welchem eine methode
ausgefuehrt werden soll, manipulieren.
die lokalen variablen einer funktion sind von ausserhalb dieses sie
einschliessenden adressraumes nicht adressierbar. werden funktionen
nur geschickt genug verschachtelt, koennen sich deren lokale variablen,
obwohl von aussen immer noch nicht zugaenglich, trotzdem durch die
adressraeume hindurch referenzieren. und ... solange referenzen von
noch *lebenden* objekten in eine eigentlich schon abgearbeitete
funktion hinein bestehen, wird diese nicht von der automatischen
--------------------------------^^^^^^^^^^
da muss ich mich korrigieren:
werden diese nicht von der automatischen
speicherbereinigung (garbage collection) erfasst.
Also kann man durch kaskadieren von funktionen verschiedene
Sichtbarkeitsbenen von variablen erzeugen, die sich durch referenzieren
zum teil umgehen lassen...
so liesse sich das formulieren ... ja.
die ueber [[Function]] referenzierten methoden [apply] und [call]
ermoeglichen es einem objekt, die methoden eines anderen objekts zu
*borgen* und im eigenen kontext auszufuehren, ohne diese methoden
selbst besitzen zu muessen.angenommen ich arbeite mit call, und ich überschreibe eine Funktion
der "Klasse" die ich über call konstruiere, wie kann ich dann noch
auf sie zugreifen? zb:function SuperCat() {
this.sound = "miaow";
}function SubCat() {
SuperCat.call(this);
/*
sehr gut, dass kommt einem klassenbasierten »super()« so nahe wie
moeglich.
dieses muster, einen weiteren konstruktor im kontext eines gerade
durch einen anderen konstruktor im instanziierungsprozess befindlichen
objekts aufzurufen, benutze ich als delegations-pattern fuer interfaces.
*/
var instance = this;
this.sound ="overridden miaow";
/*
das war es dann aber auch schon. das ueber »super()« implementierte
[[SuperCat]]-[sound] wird jetzt explizit ueberschrieben.
*/
this.makesound = function() {
alert("the cat says" + instance.sound);
}
}var felixcat = new SubCat();
felixcat.makesound();wie rufe ich den member "sound" von der mit call erzeugten instanz
der "Klasse" SuperCat auf? Ich meine wie referenziere ich diesen?
geht das überhaupt?
ja. statt des emulierten »super()« liesse sich eine [[SuperCat]]-
instanz zum prototypen eines [[SubCat]]-konstruktors bestimmen:
var SuperCat = (function () {
this.sound = "miaow";
});
var SubCat = (function () {
alert("this.constructor : " + this.constructor); // [[SuperCat]]
this.constructor = arguments.callee; // [prototype]-referenz ueberschreiben
alert("this.constructor : " + this.constructor); // [[SubCat]]
this.sound ="meow";
this.makeSound = (function () {
alert("the cat says \"" + this.sound + "\"");
});
this.makeProtoSound = (function () { // makeSuperSound
alert("the cat says \"" + this.constructor.prototype.sound + "\"");
});
});
SubCat.prototype = new SuperCat();
var felixcat = new SubCat();
felixcat.makeSound(); // "meow"
felixcat.makeProtoSound(); // "miaow"
in JavaScript waere man deshalb geradezu dazu verpflichtet,
objektkomposition auf basis wohldefinierter schnittstellen
als nativen - weil durch das sprachkonzept vorgegebenen -
vererbungsmechanismus direkt einzusetzen, statt zu versuchen,
klassenvererbung auf den gerade genannten grundlagen zu emulieren.Naja damit muss ich mich noch anfreunden...
beispiel zum anfreunden ...
gibt es dagegen eher das problem, dass nur [[SuperCat]] ein [makeSound]
zur verfuegung stellt und trotzdem nicht prototyp von [[SubCat]] sein
kann, liesse sich das problem fuer [[SubCat]]-instanzen fogendermassen
aus der welt schaffen:
var SuperCat = (function () {
this.sound = "miaow";
});
SuperCat.prototype.makeSound = (function () {
alert("the cat says \"" + this.sound + "\"");
});
var SubCat = (function () {
this.sound = "";
});
var felis = new SuperCat();
felis.sound = "meow meow meow";
var felixcat = new SubCat();
felixcat.sound = "meow";
alert(felixcat.makeSound); // [undefined]
felis.makeSound(); // "meow meow meow" - die prototypisch referenzierte methode im kontext von [felis]
felis.makeSound.call(felixcat); // "meow" - delegierter [felixcat]-kontext auf fuer [felis] erreichbare methoden
Danke für deine Mühe Peter!
nicht dafuer.
so long - peterS. - pseliger@gmx.net
bitte entschuldige die lange wartezeit - ich bin gerade vielbeschaeftigt.
Waaaas? Nein, wenn dann muss ich mich entschuldigen, dass ich dich mit meinen Anfänger-Fragen von der Arbeit abhalte! :)
Ja, für mich steht ein Konstruktor als synonym für eine klasse.
trenn Dich im kontext von JavaScript von dieser *denke*.
Wie könnte ich sonst Konkrete Objekte (per "new") erzeugen ohne
eine art "Klasse". :)auch in klassenbasierte oo benoetigst Du dazu nur den konstruktor
Nach ein bisschen vertiefung und nach 4 Videos von Douglas Crockford, beginnt sich bei mir eine Art Gefühl für JavaScript zu entwickeln :)
...Das kam weil ich die Bedeutung des Call-Operators mit der call()-
methode verwechselt hatte, welche ja ein neues objekt "konstruiert",
wobei der operator nur "aufruft" ...noe ... call-operator »()« und die call methoden »apply« und »call«
haben grundsaetzlich erstmal die gleiche aufgabe, naemlich ein
funktionsobjekt auszufuehren. ueber die beiden call-methoden lassen
sich ausserdem noch auf unterschiedlich flexible weise argumente an
eine funktion verbacken. darueber hinaus, und das ist der bei weitem
wichtigste aspekt, laesst sich der kontext, in welchem eine methode
ausgefuehrt werden soll, manipulieren.
Ja, das ist mir jetzt bewußt...
ja. statt des emulierten »super()« liesse sich eine [[SuperCat]]-
instanz zum prototypen eines [[SubCat]]-konstruktors bestimmen:
var SuperCat = (function () {
this.sound = "miaow";
});var SubCat = (function () {
alert("this.constructor : " + this.constructor); // [[SuperCat]]
this.constructor = arguments.callee; // [prototype]-referenz ueberschreiben
alert("this.constructor : " + this.constructor); // [[SubCat]]
this.sound ="meow";
this.makeSound = (function () {
alert("the cat says "" + this.sound + """);
});
this.makeProtoSound = (function () { // makeSuperSoundalert("the cat says "" + this.constructor.prototype.sound + """);
});
});
SubCat.prototype = new SuperCat();var felixcat = new SubCat();
felixcat.makeSound(); // "meow"
felixcat.makeProtoSound(); // "miaow"
>
Das Beispiel gefällt mir am Besten! So ähnlich hatte ich das auch vermutet :) Ich hatte allerdings im Web gesehen, dass man arguments.callee nur für namenlose Funktionen benutzt und es seit 1.4 als depreciated gilt. Da constructor doch ein member des SubCat Konstruktors an sich ist, kann ich doch schreiben "this.constructor = SubCat; // [prototype]-referenz", oder? Damit resette ich ihn wieder auf SubCat.
> > Danke für deine Mühe Peter!
>
> nicht dafuer.
>
Wofür sonst? :) Nochmals danke :)
so long - felix
gruss Felix,
... Ich hatte allerdings im Web gesehen, dass man arguments.callee
nur für namenlose Funktionen benutzt ...
warum nur fuer die? »this.constructor = arguments.callee;
« laesst sich
als universalbaustein doch voellig unabhaengig vom konstruktornamen
verwenden. natuerlich wird die treibende kraft hinter »arguments.callee
«
das beduerfnis gewesen sein, aus einer anonymen funktionen heraus auf
ebenjene zugreifen zu koennen, um z.b. auch namenlose funktionsobjekte
rekursiv ausfuehren zu koennen. das schraenkt aber keineswegs den
anwendungsspielraum fuer »arguments.callee
« ein.
... und es seit 1.4 als depreciated
gilt.
ganz bestimmt nicht. mit 1.4 wurde [arguments] von einer eigenschaft
eines funktionsobjekts zu einer lokalen variable eines jeden solchen
umgebogen. »arguments.callee
« wurde schon immer und auch in zukunft
dringend gebraucht. die verwendung von »arguments.caller
« hingegen
wird seit 1.3 missbilligt. mit 1.5 jedoch wurde »[Function].caller
«
eingefuehrt, sodass, wenn auch nicht ECMA-262-standardisiert, folgendes
konstrukt - »arguments.callee.caller
« - logisch ist und, wo unterstuetzt,
auch richtig waere.
gute nacht - peterS. - pseliger@gmx.net
Hallo Peter!
ganz bestimmt nicht. mit 1.4 wurde [arguments] von einer eigenschaft
eines funktionsobjekts zu einer lokalen variable eines jeden solchen
umgebogen. »arguments.callee
« wurde schon immer und auch in zukunft
dringend gebraucht. die verwendung von »arguments.caller
« hingegen
wird seit 1.3 missbilligt. mit 1.5 jedoch wurde »[Function].caller
«
eingefuehrt, sodass, wenn auch nicht ECMA-262-standardisiert, folgendes
konstrukt - »arguments.callee.caller
« - logisch ist und, wo unterstuetzt,
auch richtig waere.
Ja, ich hatte mich auch ziemlich gewundert, und ich weiß jetzt auch nicht mehr auf welcher site ich das gelesen habe. Es macht ja auch keinen Sinn eine so nützliche funktion zu depreceaten. :)
Ich habe übrigens seit 2 Tagen angefangen mich intensiv mit konstruktoren und prototypen zu Beschäftigen, denn ich denke, dass ist ein wichtiger Teil von JavaScript :)
Aber bis jetzt sind erst einmal alle Fragen geklärt...
Also noch mal vielen Dank Peter, für die freundliche Diskussion :)
(auch an struppi und co)
Bis zur nächsten Frage,
Felix
Grütze .. äh ... Grüße!
Ehm ja aber warum klappt dann das Beispiel nicht.
Wird es dadurch klarer?
function t1() {
this.v1 = "1";
t1.v2 = "2";
}
function t2() {
this.v1 = "3";
t2.v2 = "4";
}
alert(t1.v1) // --> undefined
alert(t1.v2) // --> undefined
t1()
alert(t1.v1) // --> undefined
alert(t1.v2) // --> 2
// die folgenden beiden Alerts kann ich mir eigentlich sparen, da gleiche Ausgangs-
// situation wie bei den beiden ersten Alerts
alert(t2.v1) // --> undefined
alert(t2.v2) // --> undefined
xy = new t2()
alert(xy.v1) // --> 3
alert(xy.v2) // --> undefined
alert(t2.v1) // --> undefined
alert(t2.v2) // --> 4
Cü
Kai
Wird es dadurch klarer?
[code lang=javascript]function t1() {
this.v1 = "1";
t1.v2 = "2";
}alert(t1.v1) // --> undefined
alert(t1.v2) // --> undefined
t1()
alert(t1.v1) // --> undefined
alert(t1.v2) // --> 2
Hallo Kai!
Ja schon aber wieso musst du erst
t1()
aufrufen, damit bei t1.v2 der wert 2 gelesen wird? Warum ist beim ersten abfragen von t1.v2 der wert undefined? Das ist meine eigentliche Frage!
Kannst du mir das bitte erklären :)
gruß felix
Hi,
Ja schon aber wieso musst du erst
t1()
aufrufen, damit bei t1.v2 der wert 2 gelesen wird? Warum ist beim ersten abfragen von t1.v2 der wert undefined? Das ist meine eigentliche Frage!
Die dir Cheatah bereits beantwortet hat.
MfG ChrisB
Hi,
Ja schon aber wieso musst du erst
t1()
aufrufen, damit bei t1.v2 der wert 2 gelesen wird? Warum ist beim ersten abfragen von t1.v2 der wert undefined? Das ist meine eigentliche Frage!Die dir Cheatah bereits beantwortet hat.
MfG ChrisB
wie denn??? ich versteh die antwort nicht!?
<script type="text/javascript">
function SomeClass() {
SomeClass.hallo = "hallo"; <-- hier definiere ich einen public static member
}
alert(SomeClass.hallo); <-- und hier frage ich ihn ab/rufe ich ihn über SomeClass auf!!
</script>
Was ist daran falsch??? wieso ist der wert undefined?
wie denn??? ich versteh die antwort nicht!?
Deine Antwort war leider auch nicht hilfreich.
Doch ich will, eine statische öffentliche klassen funktion haben, die auf interne private statische (instanz) variablen zugreift. Diese könnte ich nicht mit dem hinzufügen der function über prototype erreichen!
Das ist klar das du das möchtest, aber warum?
So ein Konstrukt ist äußerst selten und mit ein bisschen verbiegen, auch zu erreichen. Aber bevor ich so was machen würde, versuche ich das zu vermeiden und bisher hat das auch geklappt.
Struppi.
wie denn??? ich versteh die antwort nicht!?
Deine Antwort war leider auch nicht hilfreich.
Doch ich will, eine statische öffentliche klassen funktion haben, die auf interne private statische (instanz) variablen zugreift. Diese könnte ich nicht mit dem hinzufügen der function über prototype erreichen!
Das ist klar das du das möchtest, aber warum?
ich will doch nur eine sache wissen und das ist,warum in dem folgenden code erst nach t1() der wert bei t1.v2 = 2 ist! Mehr will ich doch gar nicht.
function t1() {
this.v1 = "1";
t1.v2 = "2";
}
alert(t1.v1) // --> undefined
alert(t1.v2) // --> undefined
t1() <-- Warum muss ich das hier schreiben damit t1.v2 = 2 ist? Das ist meine einzige frage!!
alert(t1.v1) // --> undefined
alert(t1.v2) // --> 2
HAT JEMAND EINE ANTWORT HIERFÜR?
So ein Konstrukt ist äußerst selten und mit ein bisschen verbiegen, auch zu erreichen. Aber bevor ich so was machen würde, versuche ich das zu vermeiden und bisher hat das auch geklappt.
ok dann sag mir mal wie ich in dem folge beispiel auf von f1 auf v1 zugreifen kann. Aber bitte beantworte mir erst die frage oben, denn das ist mir wirklich viel wichtiger!!
function Klasse() {
var v1 = "1"; //soll nicht sichtbar nach außen sein und nur für interne berechnungen benutzt werden!! v1 kann nicht ausgelagert werden, weil andere interne funktionionen auf sie zugreifen!
}
Klasse.f1 = function () {
//schafft keinen zugriff auf v1! deshalb soll Klasse.f1 intern sein!
};
Das ist klar das du das möchtest, aber warum?
ich will doch nur eine sache wissen und das ist,warum in dem folgenden code erst nach t1() der wert bei t1.v2 = 2 ist! Mehr will ich doch gar nicht.
Weil der Wert vorher nicht definiert wurde.
So ein Konstrukt ist äußerst selten und mit ein bisschen verbiegen, auch zu erreichen. Aber bevor ich so was machen würde, versuche ich das zu vermeiden und bisher hat das auch geklappt.
ok dann sag mir mal wie ich in dem folge beispiel auf von f1 auf v1 zugreifen kann. Aber bitte beantworte mir erst die frage oben, denn das ist mir wirklich viel wichtiger!!
function Klasse() {
var v1 = "1"; //soll nicht sichtbar nach außen sein und nur für interne berechnungen benutzt werden!! v1 kann nicht ausgelagert werden, weil andere interne funktionionen auf sie zugreifen!
}Klasse.f1 = function () {
//schafft keinen zugriff auf v1! deshalb soll Klasse.f1 intern sein!
};
Das was du willst ist eine privilegierte Funktion. In deinem Fall:
function Klasse() {
var v1 = "1";
this.f1 = function() { return v1;};
}
Das ist der Weg, den du normalerweise gehen würdest.
Struppi.
Das was du willst ist eine privilegierte Funktion. In deinem Fall:
function Klasse() {
var v1 = "1";
this.f1 = function() { return v1;};
}
> Das ist der Weg, den du normalerweise gehen würdest.
Hallo Struppi :)
Ja aber um die funktion f1 aufzurufen bräuchte ich ja eine instanz von Klasse bzw. ein konkretes objekt und das will ich ja grade nicht.
Wenn du die Javascript eigene funktion "Math" benutzt, bildest du ja auch vorher keine instanz sonder sagst ganz einfach z.B. "Math.pow", weil "pow" eine statische funktion ist!
Das was du willst ist eine privilegierte Funktion. In deinem Fall:
function Klasse() {
var v1 = "1";
this.f1 = function() { return v1;};
}
> Ja aber um die funktion f1 aufzurufen bräuchte ich ja eine instanz von Klasse bzw. ein konkretes objekt und das will ich ja grade nicht.
~~~javascript
( function() {
window.SomeClass = function (){}
SomeClass.hallo = "hallo";
})();
Wenn du die Javascript eigene funktion "Math" benutzt, bildest du ja auch vorher keine instanz sonder sagst ganz einfach z.B. "Math.pow", weil "pow" eine statische funktion ist!
Ich weiß nicht warum das dein Beispiel erklären soll:
Wenn ich Math nachbauen sollte, würde das in etwa so aussehen:~~~javascript
var myMath = new function() {
this.pow = function(a,b) { var x = a;while(--b) x *= a; return x;}
};
D.h. natürlich bilde ich eine Instanz.
Struppi.
gruss Struppi, hallo felix12,
Wenn du die Javascript eigene funktion "Math" benutzt, ...
@felix12:
[Math] ist in JavaScript einfach nur ein objekt
... bildest du ja auch vorher keine instanz ...
richtig.
sonder sagst ganz einfach z.B. "Math.pow",
weil "pow" eine statische funktion ist!
waere [Math] als singleton (als einzige instanz seiner klasse)
umgesetzt, koennte man dass mit der » ... statische funktion«
so stehen lassen.
Ich weiß nicht warum das dein Beispiel erklären soll:
»»
Wenn ich Math nachbauen sollte, würde das in etwa so aussehen:~~~javascript
var myMath = new function() {
this.pow = function(a,b) { var x = a;while(--b) x *= a; return x;}
};
>
> D.h. natürlich bilde ich eine Instanz.
@Struppi
in JavaScript gibt es mehrere moeglichkeiten, \*echte\* singletons
zu erzeugen. Dein konstrukt schrammt knapp dran vorbei, denn ueber
`var justAnotherMath = new myMath.constructor();`{:.language-javascript}
liesse sich auf einfache art eine weitere instanz erzeugen.
um dies zu verhindern sollte man die referenz auf den konstruktor
beim intanziieren ueberschreiben lassen:
~~~javascript
var myMath = new (function() {
this.constructor = Object;/*
code */
})();
so long - peterS. - pseliger@gmx.net
@Struppi
in JavaScript gibt es mehrere moeglichkeiten, *echte* singletons
zu erzeugen. Dein konstrukt schrammt knapp dran vorbei, denn ueber
var justAnotherMath = new myMath.constructor();
Danke, ich bin nach wie vor noch in der Lernphase was die ganzen Geheimnisse von OOP angehen.
Wobei ich das ein bisschen akademisch finde, da man i.d.R. ja so kein Objekt erzeugt (mit dem Aufruf von constructor).
um dies zu verhindern sollte man die referenz auf den konstruktor
beim intanziieren ueberschreiben lassen:
was im Prinzip nichts anderes als eine "Gewaltsame" Verhinderung ist. Für den OO Puristen ist das sicher die Lösung, für den JS Anwender sollte die von mir gezeigte Variante aber ausreichen, auch wenn es kein echtes Singleton ist, wird derjenige der myObjekt.constructor() aufruft schon Wissen was er macht. Und wenn man gut gewillt ist, könnte man auch sagen es ist ein Feature ;-)
Struppi.
Ja schon aber wieso musst du erst
t1()
aufrufen, damit bei t1.v2 der wert 2 gelesen wird? Warum ist beim ersten abfragen von t1.v2 der wert undefined? Das ist meine eigentliche Frage!
Weil die Funktion nicht ausgeführt wurde! Eine JavaScript-Funktionsdefinition ist etwas anderes als eine Java-Klassendefinition.
<script type="text/javascript">
function SomeClass() {
SomeClass.hallo = "hallo"; <-- hier definiere ich einen public static member
}
Nein. Wie kommst du darauf? In welcher JavaScript-Dokumentation steht, dass so (ohne weitere Befehle) ein public static member definiert wird?
function SomeClass() { // Hier beginnt eine *Funktion*sdefinition!
SomeClass.hallo = "hallo"; // Dies ist eine Befehlszeile, die erst ausgeführt wird, sobald die Funktion SomeClass aufgerufen wird (dann aber immer wieder).
}
alert(SomeClass.hallo); // Ergibt "undefined", da die oben genannte Befehlszeile nie ausgeführt wurde.
Java ist nicht JavaScript! Java hat klassenbasierte Objektorientierung eingebaut, JavaScript prototypenbaserte. JavaScript kennt Closures, Java nicht. Die beiden Programmiersprachen haben nunmal unterschiedliche Eigenschaften und du kannst nicht einfach Konstrukte aus der einen in die andere eins zu eins übertragen.
Weil die Funktion nicht ausgeführt wurde! Eine JavaScript-Funktionsdefinition ist etwas anderes als eine Java-Klassendefinition.
Ok das hilft mir weiter. :)
SomeClass.hallo = "hallo"; <-- hier definiere ich einen public static member
}
Nein. Wie kommst du darauf? In welcher JavaScript-Dokumentation steht, dass so (ohne weitere Befehle) ein public static member definiert wird?
Keine Ahnung aber eine Variable auf die ich ohne eine instanz und nur über die klasse zugreifen kann ist ja wohl statisch oder? Öffentlich ist sie ja auch...
alert(SomeClass.hallo); // Ergibt "undefined", da die oben genannte Befehlszeile nie ausgeführt wurde.[/code]
ok
Java ist nicht JavaScript! Java hat klassenbasierte Objektorientierung eingebaut, JavaScript prototypenbaserte. JavaScript kennt Closures, Java nicht. Die beiden Programmiersprachen haben nunmal unterschiedliche Eigenschaften und du kannst nicht einfach Konstrukte aus der einen in die andere eins zu eins übertragen.
nein aber prototypen regen mich ziemlich auf, weil ich über sie nicht auf instanzvariablen der superklasse zugreifen kann, wie das in c und in java möglich ist bei vererbten klassen. Das folgende geht also nicht:
»»function Klasse() {
»»var v1 = "1"; //soll nicht sichtbar nach außen sein und nur für interne berechnungen benutzt werden!! v1 kann nicht ausgelagert werden, weil andere interne funktionionen auf sie zugreifen!
»»}
»»Klasse.f1 = function () {
»»//schafft keinen zugriff auf v1! deshalb soll Klasse.f1 intern sein!
»»};
Grütze .. äh ... Grüße!
Java ist nicht JavaScript! Java hat klassenbasierte Objektorientierung eingebaut, JavaScript prototypenbaserte. JavaScript kennt Closures, Java nicht. Die beiden Programmiersprachen haben nunmal unterschiedliche Eigenschaften und du kannst nicht einfach Konstrukte aus der einen in die andere eins zu eins übertragen.
nein aber prototypen regen mich ziemlich auf, weil ich über sie nicht auf instanzvariablen der superklasse zugreifen kann, wie das in c und in java möglich ist bei vererbten klassen. Das folgende geht also nicht:
Vergiß alles, was für Java gilt.
Vielleicht ist das hier was für dich:
Javascript
advanced Javascript
Hier wird sehr detailliert auf Javascript und Vererbung eingegangen.
Brauchst allerdings ein paar Stunden Zeit ;)
Cü
Kai
Hallo Kai!
Danke für die links ich werde mir das auf jeden fall angucken! :)
Gibt es villeicht ein Archiv mit videos von douglas crockford oder generell mit guten javacript videos? Ich hatte schonmal videos von douglas gefunden aber die links waren veraltet :(
Grüße
Felix
Grütze .. äh ... Grüße!
Gibt es villeicht ein Archiv mit videos von douglas crockford oder generell mit guten javacript videos? Ich hatte schonmal videos von douglas gefunden aber die links waren veraltet :(
Weiß ich nicht. Ich kenne z.Zt. nur die Videos von seiner Seite
Cü
Kai
Grütze .. äh ... Grüße!
Weiß ich nicht. Ich kenne z.Zt. nur die Videos von seiner Seite
Nachtrag: Es war direkt vor meinen Augen ;)
Cü
Kai
Nachtrag: Es war direkt vor meinen Augen ;)
Cü
Kai
Uuuuuuuuiiii! Von genau sowas hab ich immer geträumt... so viele videos über Webprogrammierung :)
vielen Dank!
Felix
Grütze .. äh ... Grüße!
Uuuuuuuuiiii! Von genau sowas hab ich immer geträumt... so viele videos über Webprogrammierung :)
Diese Seite ist ein einziger Alptraum. Ich mache eigentlich in den letzten 1,5 Tagen nichts anderes als Essen, Schlafen, Videovorträge schauen ;)
Cü
Kai
Hallo,
statt »ich will aber ...!« zu wiederholen, solltest du dir noch einmal zu Gemüte führen, dass OOP in JavaScript ganz anders funktioniert, als du es offenbar von anderen Sprachen gewohnt bist.
Mal von Null angefangen:
1. Es gibt keine Klassen in JavaScript.
2. Es gibt keine Klassendefinitionen à la class Bla { ... } in JavaScript.
3. Es gibt keine Klassenvariablen in JavaScript, es gibt keine »privaten« und keine »statischen« Member.
Damit wird dein Wunsch »ich will aber einen public static member!« zu einem aussagelosen Satz, weil es sowas in JavaScript (erst einmal) nicht gibt. Auf die interessanteste Nachfrage antwortest du leider mit »das steht hier nicht zur Debatte«.
In JavaScript sind Funktionen Objekte. Funktionen können, wenn man sie mit dem »new«-Operator aufruft, als Konstruktoren dienen. Es wird ein neues Object (die »Instanz«) angelegt und die Funktion in dessen Kontext aufgerufen (this zeigt auf das neue Object).
D A S I S T A L L E S .
Bis dir dieses Einmaleins in Fleisch und Blut übergegangen ist, solltest du alles andere, was du über OOP aus anderen Sprachen kennst, bei der JavaScript-Programmierung erst einmal vergessen.
Und bevor du auf dieser basalen Ebene nicht mit JavaScript vertraut bist, solltest du auch nicht mit prototype, Vererbung oder Portierungen von bekannten OOP-Features in JavaScript anfangen.
Man kann viele OOP-Pattern auch auf JavaScript übertragen, indem man sie in JavaScript re-implementiert. Das ist aber immer mit Komplexität verbunden und schwer zu verstehen. Deshalb ist es in der Regel gar nicht erstrebenswert, »Java in JavaScript« o.ä. schreiben zu wollen. JavaScript hat andere Fähigkeiten und bietet eigene Möglichkeiten, um Aufgaben zu lösen. Was ist also di Aufgabe?
Mathias