molily: Private/Public/Privileged Methoden & Speichernutzung

Beitrag lesen

Hallo,

1.) Habe ich bei diesem Konzept nicht das Problem, dass bei jeder Instanz von MeineKlasse() ein neues Funktionsobjekt für die publicMethode angelegt wird?

Ja.
Es werden zwei neue Funktionsobjekte angelegt, eins für die »private« Funktion (eine lokale Variable im Konstruktor) und eines für die Instanzmethode (die als Closure wirkt).

Ich habe mal vor Urzeiten in einer ActionScript-Doku gelesen, dass das so ist, und dass man deshalb Methoden wenn irgend möglich über das Prototyp-Attribut definieren soll, weil dann immer die gleiche Methode referenziert wird (was im o.g. Fall aber ja nicht geht) - ich weiss aber nicht ob das in JavaScript auch (noch) so ist.

Ja, das gilt auch für JavaScript. (ActionScript 2 ist eine ECMAScript-3-Implementierung, JavaScript basiert ebenfalls auf ECMAScript.)

Prototypische Delegation erlaubt es, die Fähigkeiten von anderen Objekten zu nutzen, anstatt sie zu kopieren. Effektive Privatheit ist in JavaScript aber nur über Funktions-Scopes möglich. Siehe meine JavaScript-Doku:

Organisation von JavaScripten: Module und Kapselung
Organisation von JavaScripten: Konstruktoren, Prototypen und Instanzen

Insbesondere:
Nachteile von privaten Objekten
Wozu Kapselung gut ist und wann sie nötig ist

2.) Wenn das tatsächlich so ist (dass jede Instanz das Funktionsobjekt neu erzeugt), verschwende ich bei vielen Instanzen ja ganz schön Speicher

Ja, richtig.

Die JavaScript-Engine kann das ggf. optimieren, weil der Code der Funktion immer derselbe ist, lediglich die Scope-Chain ändert sich. Aber im Grunde stimmt es, dass hier unzählige gleiche Funktionsobjekte erzeugt werden.

Wenn man effektive Privatheit von Daten haben will, führt nichts daran vorbei, als mit verschachtelten Funktionen zu arbeiten. Das ist nicht die nicht schnellste und sparsamste Möglichkeit, aber es führt nicht notwendig zu merklichen Performance-Einbußen. Es ist immer die Frage, wie oft und wie häufig du diesen Code aufrufst und wie viel Platz die Funktionen im Speicher wirklich brauchen. Ich würde behaupten, dass du selbst in einer großen JavaScript-Anwendung in aktuellen Browsern keine Performance-Nachteile spürst, wenn du nicht gerade Millionen Instanzen erzeugst.

Natürlich ist das Erzeugen von Instanzen mit solchen »privaten« Funktionen tausendmal langsamer als mit öffentlichen. Aber diese Operationen steht in keinem Verhältnis zu anderen üblichen Operationen in JavaScript-Anwendungen. Jede noch so einfache DOM-Operation wird tausendmal langsamer sein als das Anlegen einer Millionen Funktionen. Auf älteren Browsern oder Geräten mit begrenztem Speicher kann es natürlich anders sein.

Die schnellste und sparsamste Methode wäre die Nutzung von pseudo-privaten Methoden, die nicht effektiv privat sind, sondern Eigenschaften des Prototype. Sie werden bloß per Konvention nicht von außerhalb aufgerufen. Der Name solcher Methoden beginnt üblicherweise mit dem Unterstrich.

Generell gilt: Don’t optimize prematurely. Wenn ein JavaScript langsam läuft oder zuviel Speicher verbraucht, sollte man es profilen und die Stellen optimieren, die am langsamsten laufen bzw. am meisten Speicher belegen. Es ist möglich, aber unwahrscheinlich, dass solche privaten Funktionen die Performance-Bremsen in einer JavaScript-Anwendung sind.

Siehe auch meinen Artikel Performance von JavaScript-Closures.

Mathias