Aber das Problem ist, du kannst mit JS nicht wirklich OO programmieren. Du kannst versuchen einige Muster umzusetzen und du musst hoffen, dass du nichts durcheinander bringst, wenn du mit einem Framework arbeitest das versucht diesen Mangel etwas zu lindern. Aber es fehlen die grundlegendsten Dinge, echte private Member, auf die du z.b. auch in den prototype Funktionen zugreifen kannst und protected geht gar nicht mehr.
Peter hat zu der Frage ja eigentlich alles schon gesagt, die Soshnikov-Artikel wurden auch schon verlinkt. Dennoch will ich noch etwas einwerfen.
OOP heißt für mich erst einmal, dass es Objekte als Gruppierungen von Daten und Funktionalität gibt und diese Objekte einander Nachrichten senden: »Alan Kay coined the phrase Object-Oriented Programming, but this is not his fault. He has repeatedly said that to him, OOP is about encapsulation and message passing, not inheritance and ontologies of types.« (Quelle) Weitere OOP-Konzepte bauen darauf auf. Das alles macht man nicht zum Selbstzweck, sondern weil man sich davon Vorteile entspricht.
Zu dem wichtigsten gehört wohl die Kapselung bzw. das Information Hiding. Das ist, wie Soshnikov erklärt, erst einmal eine Technik zur Verbesserung der Datenstrukturierung vom Programmierer für den Programmierer. Er zeigt das anschaulich daran, dass die Sprachen Python und Ruby zwar public/protected/private unterscheiden, aber dies nicht mehr als eine Metainformation ist. Mit Tricks ist der Zugriff trotzdem möglich. Das ist kein Widerspruch zum Kapselungskonzept. Offenbar gilt ähnliches auch für andere Sprachen, Wikipedia schreibt: »Almost always there is a way to override such protection«, auch in C++ und Java.
Die Unterscheidung zwischen public und private soll also erst einmal mein Denken, meine Strukturierung des Programms, mein Design des Objekt-Messagings verbessern, indem ich klar definiere, auf was für Nachrichten das Objekt nach außen reagier, welche Daten es geordnet herausgibt und welche es für sich behält. Alles andere sind Interna, die ich wiederum ordentlich zu strukturieren habe. Dabei hilft mir OOP nur bedingt weiter.
Eine zweite große OOP-Idee ist, dass Funktionalität von Objekten wiederverwendet wird. Dass das nötig und nützlich ist, liegt auf der Hand. Dazu gibt es, soweit ich das verstehe, zwei (sich nicht ausschließende) Richtungen, die der Composition mit Traits, Mixins und Hat-Beziehungen sowie die der Delegation und der Vererbung. Abstrakte Typen wie Klassen und Interfaces sind eine andere Ebene und bauen auf den genannten Ansätzen auf. (So erkläre ich mir das - denn es lässt sich ja selbst bei prototypischer Delegation ein »abstraktes« Objekt erzeugen, das selbst nur als Prototyp dient.)
Es gibt also ein breites Feld von OOP-Konzepten für Code Reuse. Manche davon sind bereits in JavaScript eingebaut, andere lassen sich problemlos mit JavaScript-Mitteln umsetzen. Was hingegen schwierig ist und immer schwierig sein wird, ist eine gewisse OOP-Umsetzung möglichst getreu zu kopieren. Der plausible Beweggrund dafür kann nur der sein, dass man Kenner dieser OOP-Umsetzung gewinnen will. Dahinter kann noch der Grund stehen, die Disziplin und den Zwang einer strengen, statischen Sprache auf JavaScript zu übertragen.
Die Idee ist an sich nicht schlecht. Aus solchen Überlegungen entstanden CoffeeScript, aber auch Objective-J und der Google Web Toolkit. PrototypeJS hat beispielsweise viele Ideen von Ruby und Ruby on Rails geerbt. Das alles funktioniert hervorragend, solange Maßstab nicht lautet: Wie exakt kann ich Java-Klassen in JS umsetzen? Sondern: Welche (bekannten, gerne entlehnten) OOP-Konzepte helfen mir, meine Probleme strukturiert in Code auszudrücken? Welche OOP-Konzepte passen zu JS und wie setze ich sie um?
Da kann natürlich auch so etwas radikales wie Objective-J oder GWT herauskommen, wo JavaScript nur noch die Sprache ist, in die kompiliert wird. Der Mainstream geht jedoch – meiner Ansicht nach aus guten Gründen – eher dahin, bei JavaScript die »Good Parts« nicht zu überdecken und die Expressivität nicht einzuschränken, sondern die wirklichen Anwendungsprobleme (Native Objects, der Browser, das DOM, fortgeschrittenes OOP) zu vereinfachen.
Das hat sicher Vor- und Nachteile. jQuery beispielsweise bietet einem recht wenig Halt, weil es keine umfassendere Philosophie wie etwa PrototypeJS hat. Man kann totalen Spaghetticode in jQuery schreiben, aber auch sehr gut strukturierten und dabei von vielen abstrakten jQuery-Konzepten Gebrauch machen. jQuery ist vielleicht auch deshalb so erfolgreich, weil es einerseits eine recht einheitliche, funktionale API für DOM-Operationen und Event-Handling hat, aber keine Grobstrukturierung erzwingt. Das heißt, dass Einsteiger ohne JavaScript-Hintergrundwissen damit erst einmal Spaghetticode schreiben werden. Fortgeschrittenen obliegt es, Object-Literale, Revealing Modules, prototypische Delegation, Pseudoklassen, komplexere OOP-Bibliotheken usw. einzusetzen.
Mathias