ebody: Wie kann man in Javascript einer Klassen Instanz ein neues Argument übergeben?

Hallo,

Beispiel:

class check{
 constructor(url) {
    this.url= url;
 }

  _checkUrl(){
   // Prüfe this.url
  }
}
    
let check1 = new check("https://www.example.com/");

{...Script welches sich häufig auf die Instanz "check1" bezieht...}

Das ist alles sehr verkürzt dargestellt. Das Script wird erweitert und bezieht sich häufig auf die Instanz check1. Daher kann ich keine neue Instanz erstellen.

Die URL kann über ein Textfeld vom Nutzer geändert werden. Ich müsste das Argument aus dieser Zeile also ändern:

let check1 = new check("https://www.example.com/");

Die Instanz check1 muss bestehen bleiben. Wie kann ich das neue Argument in einem solchem Fall übergeben?

So funktioniert es nicht:

check1("https://www.example.test/");

Die einzige Möglichkeit die ich momentan sehe ist, das Argument über eine setter Funktion zu übergeben.

class check{
 constructor() {
 }

  set _checkUrl(url){
   // Prüfe url
  }
}
    
let check1 = new check("https://www.example.com/");

{...Script welches sich häufig auf die Instanz "check1" bezieht...}

// Neue URL wird übergeben
...
check1._checkUrl = "https://www.example.test/";
...

Aber wäre das wirklich die einzige, beste Möglichkeit?

Gruß ebody

Moderationshinweis: URLs durch Beispiel-URLs ersetzt

  1. Tach!

    Die einzige Möglichkeit die ich momentan sehe ist, das Argument über eine setter Funktion zu übergeben.

    Aber wäre das wirklich die einzige, beste Möglichkeit?

    Du kannst außerdem noch eine Methode schreiben, die this.url setzt und weitere Aktionen auslösen kann, oder einfach nur this.url einen neuen Wert zuweisen, was dann aber keine weiteren Aktionen auslösen kann. Ob Setter oder Funktion ist Geschmackssache, beides kapselt den direkten Zugriff gleichermaßen gut.

    dedlfix.

  2. Ich sehe jetzt im Moment keinen Grund, warum du überhaupt eine Klasse benutzt bzw. warum du unbedingt für verschiedene URLs dasselbe Objekt benutzen willst.

    Entweder möchtest du während des Skriptlaufes nur diverse URLs auf Gültigkeit prüfen, dann benutze die Funktion checkurl() direkt.

    Oder du möchtest mit einer URL, nachdem sie geprüft wurde, noch andere Sachen machen (zum Beispiel URL-Teile wie die Parameter auslesen). Dann benutze für jede neue URL auch eine neue Instanz.

    Klassen sind kein Ersatz für Funktionen und ein Objekt sollte immer denselben Satz Daten enthalten (die sich im Objekt natürlich ändern können, aber es sollten keine komplett neuen, unabhängigen Daten in ein bereits benutztes Objekt geschrieben werden).

    check1 ist im Übrigen auch kein Objekt, sondern eine Variable, die auf ein Objekt zeigt. Du kannst im Skript überall check1 nutzen, selbst wenn du check1 mit neuen URLs fütterst; du musst nicht das erste erzeugte Objekt mit neuen Daten bestücken.

    1. Hallo und vielen Dank an alle für eure Hilfe.

      In der Klasse wird eine Google Spreadsheet URL die ein JSON zurückgibt ausgelesen und die Daten aus der Tabelle in ein neues Array geschrieben, wobei die Elemente des Arrays Objekte sind. Jedes Objekt enthält eine Zeile und die Keys sind die Spaltenüberschriften.

      In dem Script welches diese Klasse nutzt wird check1 immer wieder verwendet

      let check1 = new check("https://www.example.com/");

      Das Script fängt z.B. Klicks auf verschiedene Button ab, die dann eine Funktion auslösen und check1 verwendet wird, z.B. check1.listAll() oder check1.listColumn('Name')

      Wenn ich jetzt immer eine neue Instanz erzeugen würde, wenn sich die URL ändert, müsste ich in dem Script check1 immer wieder durch die neue Instanz ersetzen.

      Daher denke ich zumindest, dass es in diesem Fall sinnvoll ist, nur die URL ändern zu können.

      Aber ich programmiere noch nicht all zu lange mit Klassen und daher wäre es gut möglich, dass ich einen falschen Weg einschlage. Da ich gerade an einem Script arbeite, was immer weiter wächst, kommen immer mehr Situationen, wo ich mich frage, wann soll ich eine Klasse verwenden, wann eine erweitertete Klasse, wann eine neue Klasse, welche Funktionen etc. gehören wirklich darein und welche außerhalb der Klassen. Aber es ist ein interessanter/schöner Lernprozess.

      Gruß ebody

      1. Hallo ebody,

        wie schon Tantchen Wilhelmine sagte - check1 ist eine Variable. Wenn die für dein Script global ist, kannst du den Wert von check1 durch ein neues Objekt ersetzen und alle folgenden Zugriffe verwenden dann das neue Objekt.

        Ob das gute Architektur ist? Keine Ahnung; dazu müsste man wissen, wie dein Script als Ganzes organisiert ist. Grundsätzlich sollte man nicht zu große Funktionen oder Klassen haben, eine Gliederung nach Komponenten ist sinnvoll. Ein Objekt wie check, das ggf. von vielen Komponenten gebraucht wird, könnte man beim Erzeugen dieser Komponenten an den Konstruktor übergeben ("injizieren"). Man könnte auch eine Klasse "ApplicationContext" haben, deren Eigenschaften die global benötigten Werte und Objekte bereitstellen - das kann okay sein, oder eine versteckte Form von COBOL-Programmierung (wo alle Variablen global sind).

        Wenn das Objekt check an diverse Komponenten übergeben wird, so dass es mehrere Variablen gibt, die alle auf dieses Objekt zeigen, dann brauchst Du einen Mechanismus, der ein neues Spreadsheed lädt. Das würde ich dann vom Konstruktor trennen und statt dessen eine load-Methode schreiben, der man die URL übergibt, die das Spreadsheed lädt und das Ergebnis passend umbaut.

        Wenn eine Variable check1 von diversen Komponenten genutzt wird, d.h. es gibt nur eine einzige Stelle, die auf das check-Objekt zeigt, dann kannst Du ein neues Objekt anlegen und die check1-Variable überschreiben. Und zwar genau dann, wenn der Lade- und Transformationsvorgang beendet sind. Auch hier empfiehlt sich eine Trennung von Konstruktor und Ladevorgang. Eine load-Methode könnte ein Promise zurückgeben, und dieses Promise erfüllst Du ("resolve"-Aufruf), sobald der fetch des JSON-Strings und dessen Transformation beendet sind. Das sind asynchrone Abläufe, die muss man sauber steuern.

        Rolf

        --
        sumpsi - posui - obstruxi
  3. Hallo ebody,

    Ob es richtig ist, dass dein Script überall auf das in check1 gespeicherte Objekt zugreift, kann durchaus ein Punkt zum diskutieren sein. Aber dafür müsste man viel mehr wissen, deswegen lasse ich das sein.

    Wenn du eine Objekt Instanz hat und darin eine Eigenschaft ändern willst, brauchst du entweder eine öffentliche Eigenschaft oder eben getter und setter.

    Eigenschaften sind in JavaScript immer öffentlich, es sei denn man ergreift Maßnahmen um sie zu verstecken (Tipp für Recherche: "javascript private properties").

    Ein setter ist nur dann zwingend nötig wenn mehr passieren soll als nur einen neuen Wert zu speichern. Du könntest die URL validieren wollen. Dein check Objekt könnte ein change Event auslösen wollen, auf das sich andere registrieren um die URL Änderung mitzubekommen. Alles denkbar. Und hängt komplett von deiner spezifischen Anwendung und ihrer Architektur ab. Das kann man nicht allgemein bewerten.

    Rolf

    --
    sumpsi - posui - obstruxi