Was ich versuche zu erreichen, ist die Erstellung von Funktionen, die auf Eigenschaften eines Objekts in JavaScript arbeiten, was eine ziemlich typische Sache ist.
Das Problem besteht darin, dass ich im Interesse der Flexibilität und Erweiterbarkeit nicht möchte, dass die Funktionen im Voraus über das Objekt Bescheid wissen. Soweit ich das beurteilen kann, ist dies genau die Art von Sache, für die JavaScript ziemlich gut geeignet sein sollte. Da ich jedoch noch nicht viel Zeit in funktionalen Sprachen verbracht habe, habe ich noch nicht herausgefunden, wie man das macht.
Also könnte ich in einer Situation wie dieser sein:
function Owner()
{
var self=this;
self.size = 100;
self.writers = [];
}
function Writers()
{
var Alice= function()
{
var that=this;
that.name="alice";
that.operate = function()
{
console.log( "Alice says: "+self.size );
}
}
this.alice=new Alice();
}
var owner = new Owner();
var writers = new Writers();
owner.writers.push( writers.alice );
owner.writers[0].operate();
Jetzt gibt dies Alice sagt: undefined
zurück, was alles gut und schön ist, aber nicht genau das, was ich suche- am liebsten würde ich Alice sagt: 100
sehen. In einer klassischen Sprache müsste ich wahrscheinlich der Alice-Funktion einen Verweis auf den Owner geben (in Pseudo-C#):
public class Owner()
{
private List writers;
public Owner()
{
this.size=100;
this.writers= List();
}
public int Size{ get; set; }
public void AddWriter( Writer writer )
{
writer.Owner = this;
this.writers.Add(writer);
}
}
public class Writer
{
private Owner owner;
private string name;
public void Writer( string name )
{
this.name=name;
}
public void operate()
{
Console.WriteLine( "{0} sagt: {1}", name, owner.Size );
}
}
Soweit ich das beurteilen kann, ist das nicht sehr Javascripty- es scheint, dass es einen besseren- oder zumindest einen idiomatischeren - Weg geben sollte, dies zu tun.
In Bezug auf das eigentliche Ziel des Codes, an dem ich arbeite (der grundsätzlich wie dieser, aber komplizierter ist), besteht das Ziel darin, beliebig viele "Writer"-Klassen hinzufügen zu können, die Operationen auf der "Owner"-Instanz durchführen können, an die sie angehängt sind. Dies ist im Grunde eine Implementierung des Decorator
-Musters und ich kann mir viele Möglichkeiten vorstellen, wie ich das umsetzen könnte, aber wie gesagt, ich versuche zu verstehen, wie mir die funktionalen/prototypischen Eigenschaften von JavaScript in dieser Art von Situation helfen können, damit ich die Sprache besser verstehe.
Ich bin auch nicht ganz zufrieden damit, wie ich die Funktionen durch Instanzen herumreiche- ich habe das Gefühl, dass ich Funktionen wie Konfetti herumschmeißen können sollte. Daher wären Tipps dazu, wie dies mit dem Variablenscope interagiert, sehr hilfreich.
Wenn sich herausstellt, dass das, was ich versuche, rückwärts ist und es einen besseren Weg gibt, dieses Ziel zu erreichen, ist das auch in Ordnung. Ich versuche, die gute Sprache in JavaScript zu erreichen und es ist schwierig, aber ich lerne eine Menge dabei.
Bearbeitung: Mein Ziel ist es, einen Basistyp zu haben, bei dem ich bei der Gestaltung nicht die vollständige Liste der Operationen kennen muss, die er ausführen könnte, und bei dem ich nicht für jede verschiedene Kombination verfügbarer Operationen eine neue Unterklasse erstellen muss, um sicherzustellen, dass meine Operationen von meinen Kernarten entkoppelt sind.
Wenn ich also einen Tier
-Typ habe und meine Operationen Fressen
, Laufen
, Wachsen
usw. waren, würde ich idealerweise einen Aufruf vom Typ myAnimal.can("Fressen")
haben (...). Wenn die Fressen
-Aktion aufgerufen würde, würde dies die Eigenschaften des übergeordneten myAnimal
-Objekts beeinflussen. Während der Lebensdauer von myAnimal
könnten Fähigkeiten jederzeit hinzugefügt oder entfernt werden, aber solange man prüft, ob es etwas tun kann, sollte das für meine Bedürfnisse ausreichen.