In letzter Zeit habe ich ein bißchen versucht, was mit JavaScript zu machen. Im naiven Bestreben, Dinge „gut“ zu machen, bedeutet(e) das auch, viel zu lesen - z.B. über best practices. Dass dazu im Detail jeder etwas anderes schreibt, ist klar - aber bei JavaScript schreibt jeder zu den elementarsten Dingen etwas anderes. Vielleicht verbessert sich mein (bisher recht schlechter) Eindruck noch, wenn sich das Verständnis etwas vertieft.
Aber eine Sache erscheint mir im Moment haarsträubend:
Man kann „„Objekte““ um Properties erweitern. Man kann also sowas machen wie
var called = function(someObject)
{
someObject.canYouRelyOnThis = undefined;
someObject.whereDoesThisComeFrom = "you never know";
}
var caller = function()
{
var someObject = {};
someObject.canYouRelyOnThis = "yes";
called(someObject);
console.log(someObject.whereDoesThisComeFrom); // Gibt "you never know" aus...
if (typeof someObject.canYouRelyOnThis === "undefined") console.log("No, you cannot"); // Gibt "no, you cannot" aus...
}
Ja, man kann sich Objekte wie eine Große „Map“ vorstellen, und damit ist klar, warum das geht.
Aber…
— (hier geht der Rant-Teil los) —
[ot]
Ähm. Mal im Ernst:
:sick: :suspect: WTFITS!? :verzweifel:
Üblicherweise lege ich (in Java und C++, würde das aber auch in anderen Sprachen (gerne) versuchen) Wert auf ein klares Datenmodell. Datenmodellklassen sind bei mir üblicherweise interfaces. Eine public class
verursacht bei mir schon Bauchschmerzen. Wenn irgendeine Methode sichtbar ist, die nicht Teil eines idealisierten Modells ist, fühle ich mich unwohl. Wenn jemand etwas aufrufen kann oder verändern kann, was auch nur ansatzweise dazu beiträgt, dass der Zustandsraum der Objekte umklarer wird, ist das IMHO ein Problem.
Und in JavaScript kann jeder beliebig und völlig frei an Objekten rumpfuschen, properties und sogar Funktionen hinzufügen oder rauswerfen oder durch eigene ersetzen. Auf Javaisch würde das bedeuten:
Object object = new Object();
magic(object); // Macht... was auch immer
System.out.println(object.toString()); // Startet MineSweeper und formatiert die Festplatte
Wie soll man mit so einer Sprache vernünftige, nachhaltige Software entwickeln? Wie kommt man damit klar, dass man NIE weiß, was mit einem Objekt passiert, das man an irgendeine Library-Funktion übergibt (wenn man weiß, dass mit diesem Objekt ALLES passieren kann - inklusive kann es komplett „kaputt“ gemacht werden!)
[/ot]
— (hier endet der Rant-Teil) —
Gibt es irgendwelche Konventionen dazu, ob Funktionen übergebene Objekte verändern dürfen? Speziell ob irgendwelche Funktionen „ihre“ Datein einfach mit in Objekte reinpacken dürfen? Oder, als ganz konkretes (wenn daher auch eingeschränkt repräsentatives) Beispiel: Auf WebGL Lesson 1 – A triangle and a square | Learning WebGL steht folgende Funktion:
var gl;
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch(e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-( ");
}
}
Wer weiß nun woher, dass „gl.viewportWidth“ einen Wert zugewiesen bekommt? Was IST gl
in diesem Fall? Ja, ersmal ein GL-Kontext - aber eben mit irgendwelchen willkürlich reingemischten Properties, die der Autor an dieser Stelle zufällig praktisch fand?! :sick: Und woher weiß man, dass eine Library-Funktion wie
function renderWith(gl) {
...
}
nicht sowas macht wie
gl.viewportWidth = "Ätsch, ich bin jetzt ein String!";
?!? :suspect:
(Wenn ich es richtig verstanden habe, kann man für letzteres wohl mit „defineProperty“ da einige Einschränkungen vornehmen, aber die grundsätzlichen Möglichkeiten sind ja sprachinhärent…)