MB: Tutorials für JavaScript Patterns gesucht

nabend Community,

wo finde ich hier ein Tutorial für JS Patterns?

Ich hab mal unteranderem auf YouTube gesucht und gefunden. Das ist leider auf Englisch und beinhaltet viele neue Funktionen z.B. prototype oder call. Diese sind glaube ich in der aktuellen JS Version Aufgelistet und gabs früher noch nicht.

Tutorials auf YouTube sind meines erachtens für den kleinen Einstieg gut wenn man der Englichen Sprache und den akzenten mächtig ist was ich nicht bin.

LG MB

  1. Hallo MB

    Ich hab mal unter anderem auf YouTube gesucht und gefunden. Das ist leider auf Englisch und beinhaltet viele neue Funktionen z.B. prototype oder call. Diese sind glaube ich in der aktuellen JS Version aufgelistet und gabs früher noch nicht.

    Weder prototype noch call sind in irgendeiner Form neu, und bei prototype handelt es sich zumindest auf Sprachebene auch nicht um eine Funktion, jedenfalls in der Regel nicht. Eine Ausnahme von der Regel ist allerdings Function.prototype, dessen eigene Methode call ist. Aber das ist in diesem Zusammenhang kaum relevant.

    Die Eigenschaft prototype von Funktionsobjekten dient der Implementierung prototypischer Vererbung und ihr Wert ist üblicherweise ein gewöhnliches Objekt; Wird eine Funktion als Konstruktor aufgerufen, also entweder durch den Operator new oder unter Verwendung der Methode Reflect.construct, dann wird von der Funktion automatisch ein neues gewöhnliches Objekt erzeugt und zurückgegeben.

    Dieses erzeugte Objekt wiederum hat eine Verbindung zu der Eigenschaft prototype des Konstruktors, das heißt, der Prototyp des erzeugten Objektes ist der Wert dieser Eigenschaft. Ist nun, wie dies standardmäßig der Fall ist, als Wert der Eigenschaft prototype ein Objekt hinterlegt, dann können dessen Eigenschaften und Methoden auch über das neu erzeugte Instanzobjekt referenziert werden; Sie werden also an dieses Objekt vererbt.

    Sehen wir uns das Ganze aber mal an einem Beispiel etwas genauer an, wobei wir zunächst eine Funktion definieren, die wir dann später als Konstruktor aufrufen werden; Weil abgesehen von Pfeilfunktionen prinzipiell alle selbstdefinierten Funktionen als Konstruktor verwendet werden können, spielt die Art der Definition dabei keine Rolle.

    Das heißt, es ist unerheblich, ob die Funktion wie im folgenden Beispiel deklariert wird, oder ob sie als Ausdruck notiert und das Funktionsobjekt einer Variable, Konstante oder Objekteigenschaft als Wert zugewiesen wird. Zu beachten ist hier ersteinmal nur die allgemeine Konvention, den ersten Buchstaben des Funktionsbezeichners groß zu schreiben, wodurch die Absicht zum Ausdruck gebracht wird, diese Funktion als Konstruktor zu verwenden.

    function Constructor ( ) {
      'use strict';
      this.property = 'value';
    }
    

    Wird eine Funktion als Konstruktor aufgerufen, dann wird wie gesehen ein neues Objekt erzeugt. Dieses Objekt kann innerhalb des Funktionskörpers über die Kontextvariable this angesprochen werden, sprich, die Funktion wird beim Aufruf als Konstruktor im Kontext des Instanzobjektes ausgeführt.

    Entsprechend können wie in dem Beispiel oben bereits bei der Ausführung des Konstruktors eigene Eigenschaften und Methoden auf dem erzeugten Objekt definiert werden. Hier also eine Eigenschaft mit dem Namen property, welcher der der Wert 'value' zugewiesen wird. Jede von diesem Konstruktor erzeugte Instanz besitzt demnach also selbst eine solche Eigenschaft.

    Zu beachten ist hier darüber hinaus die Anweisung 'use strict', die dafür sorgt, dass die Funktion Constructor im Strict Mode ausgeführt wird. Dies ist eine Vorsichtsmaßnahme um zu verhindern, dass versehentlich globale Variablen erzeugt werden, wenn die Funktion nicht als Konstruktor aufgerufen wird.

    Denn im normalen Ausführungsmodus verweist this bei einem gewöhnlichen Funktionsaufruf auf das globale Objekt, also üblicherweise window, dessen Eigenschaften in der Regel gleichzeitig globale Variablen sind. Würde Constructor also im normalen Ausführungsmodus aufgerufen und dabei das Schlüsselwort new vergessen werden, dann würde eine neue globale Variable mit dem Bezeichner property angelegt.

    Im Strict Mode ist der Wert von this bei einem normalen Funktionsaufruf hingegen nicht window, sondern der primitive Wert undefined. Das heißt, in dem Fall, dass beim Aufruf das Schlüsselwort new vergessen wird, würde keine globale Variable angelegt, sondern die Zuweisung würde einen Fehler produzieren.

    function Constructor ( ) {
      if (!new.target) {
        throw new TypeError('Constructor called without new');
      }
      this.property = 'value';
    }
    

    Zu diesem Zweck könnte man übrigens auch den Operator new.target verwenden, der im Falle des Aufrufs als Konstruktor auf die aufgerufene Funktion verweist, hier also Constructor, sonst jedoch den Wert undefined zurückgibt. Hierbei handelt es sich allerdings in der Tat um ein relativ neues Feature, dass gegebenenfalls noch nicht von allen relevanten Ausführungsumgebungen unterstützt wird.

    console.log(typeof Constructor.prototype); // object
    

    Jedenfalls besitzt unser Konstruktor wie alle gewöhnlichen Funktionen eine Eigenschaft mit dem Namen prototype, in der ein planes Objekt hinterlegt ist. Dieses Objekt besitzt standardmäßig nur eine eigene Eigenschaft, nämlich die Eigenschaft constructor, welche eine Referenz auf das dazugehörige Funktionsobjekt enthält, hier also auf unsere Funktion Constructor.

    const value = Constructor.prototype.constructor;
    
    console.log(value === Constructor); // true
    

    Nun definieren wir auf dem Objekt, welches in der Eigenschaft Constructor.prototype hinterlegt ist eine Methode, welche die Anweisung beinhaltet, den Wert der Eigenschaft property des Objektes zurückzugeben, in dessen Kontext die Methode ausgeführt wird.

    Constructor.prototype.method = function ( ) {
      return this.property;
    };
    

    Dabei ist zu berücksichtigen, dass die Kontextvariable this im Falle eines Methodenaufrufs immer auf das Objekt zeigt, auf dem die Funktion aufgerufen wurde. Das heißt, wenn der Aufruf über einen Elementausdruck nach dem Schema object.method() erfolgt, dann ist der Wert von this innerhalb der Funktion immer das Objekt, über das die Funktion beim Aufruf referenziert wurde.

    const instance = new Constructor;
    
    console.log(typeof instance); // object
    

    Nachdem wir nun also eine Konstruktorfunktion erstellt haben und auf dem Objekt, welches in der Eigenschaft prototype hinterlegt ist, eine Methode definiert haben, rufen wir die Funktion jetzt mittels des Operators new als Konstruktor auf, sodass ein neues Objekt erzeugt und zurückgegeben wird, das in der Konstante mit dem Bezeichner instance gespeichert wird.

    Da der Aufruf von Constructor durch den Operator new erfolgt und wir hier keine Argumente an die Funktion übergeben, können wir uns die Notierung der runden Klammern nach dem Funktionsbezeichner sparen.

    console.log(instance.hasOwnProperty('property')); // true
    
    console.log(instance.property); // value
    

    Unser auf diese Weise erzeugtes Instanzobjekt besitzt nun eine eigene Eigenschaft namens property deren Wert der String 'value' ist, da wir im Funktionskörper unseres Konstruktors die entsprechende Zuweisung vorgenommen haben. Aber das ist natürlich nicht alles.

    console.log(instance.hasOwnProperty('method')); // false
    
    const value = instance.method( );
    
    console.log(value); // value
    

    Denn wir haben auf dem Objekt Constructor.prototype ja noch eine Methode mit dem Namen method definiert. Diese Methode wird nun bei der Erzeugung des Instanzobjektes nicht auf dieses kopiert, weshalb die Überprüfung mittels hasOwnProperty, ob es sich um eine eigene Eigenschaft handelt, entsprechend das Ergebnis false ergibt; Aber sie kann dennoch auf der Instanz aufgerufen werden, da Constructor.prototype der Prototyp dieses Objektes ist.

    Das heißt, bei dem Versuch, die Methode method auf instance zu referenzieren wird intern zunächst geprüft, ob das Objekt instance selbst über eine solche Methode verfügt. Was hier nicht der Fall ist. Da die Suche auf diesem Objekt also erfolglos bleibt, wird in einem zweiten Schritt nachgesehen, ob der Prototyp von instance über eine entsprechende Methode verfügt.

    const proto = Object.getPrototypeOf(instance);
    
    console.log(proto === Constructor.prototype); // true
    

    Da der Prototyp von instance nun das Objekt Constructor.prototype ist und weil auf diesem Objekt eine Methode mit dem Namen method definiert ist, wird schließlich diese Methode referenziert und im Kontext des Objektes instance aufgerufen, sodass im Ergebnis der Wert der Eigenschaft property von instance zurückgegeben wird. Die Methode method wird also von Constructor.prototype an instance vererbt.

    Nun haben wir in den Beispielen oben darüber hinaus zweimal die Methode hasOwnProperty auf dem Instanzobjekt aufgerufen, bei der es sich ebenfalls nicht um eine eigene Methode dieses Objektes handelt, sondern um eine Methode, die eigentlich auf dem Objekt Object.prototype definiert ist.

    console.log(Object.prototype.hasOwnProperty('hasOwnProperty')); // true
    
    const proto = Object.getPrototypeOf(Constructor.prototype);
    
    console.log(proto === Object.prototype); // true
    

    Da Object.prototype jedoch der Prototyp von Constructor.prototype ist, und weil wie gesehen beim Zugriff auf eine Eigenschaft oder Methode auch die jeweiligen Prototypen durchsucht werden, wird die Methode hasOwnProperty ebenso wie die Methode method beim Aufruf auf instance über die Prototypenkette referenziert.

    Der Zweck der Eigenschaft prototype von Funktionsobjekten ist also, allen von der Funktion erzeugten Objekten Methoden und Eigenschaften zur Verfügung zu stellen, ohne diese auf den Objekten selbst definieren zu müssen.

    Darum spricht man hier auch von Differenzieller Vererbung, das heißt, ein Prototyp stellt die Funktionalität zur Verfügung, die bei allen von diesem Prototypen erbenden Objekten vorhanden sein soll, während auf den Instanzobjekten selbst nur die Unterschiede, also die Differenzen definiert werden müssen.

    Eine etwas ausführlichere Erklärung zu dem Thema bietet der Artikel Vererbung im Wiki.

    Es soll allerdings nicht verschwiegen werden, dass die Erzeugung von Objekten durch den Aufruf einer Funktion oder Klasse mittels new nicht die einzige Möglichkeit darstellt, prototypische Vererbung zu implementieren.

    const proto = {
      method ( ) {
        return this.property;
      }
    };
    
    const instance = Object.create(proto);
    
    instance.property = 'value';
    
    console.log(instance.method( )); // value
    

    Zu diesem Zweck kann nämlich auch die Methode Object.create verwendet werden, welche ein neues planes Objekt erzeugt und als dessen Prototyp das Objekt installiert, welches der Methode als erstes Argument übergeben wurde.

    Was nun die Methode call angeht, ist zu erwähnen, dass diese auf Function.prototype definiert ist, und da alle Funktionen von Function.prototype erben, kann sie entsprechend auch auf allen Funktionen aufgerufen werden.

    Die Methode call ermöglicht es, eine Funktion in einem bestimmten Kontext aufzurufen. Das heißt, die Kontextvariable this der auf diese Weise aufgerufenen Funktion wird mit dem Wert initialisiert, welcher der Methode call als erstes Argument übergeben wurde.

    function getThis (parameter) {
      console.log(parameter);
      return this;
    }
    
    const result = getThis.call('value', 'argument'); // argument
    
    console.log(result); // value
    

    Mit den weiteren an die Methode call übergebenen Argumenten wird dann die Funktion aufgerufen, auf der die Methode ausgeführt wird, weshalb der Parameter in dem Beispiel oben mit dem String 'argument' initialisiert wird.

    Soll eine Funktion also explizit in einem bestimmten Kontext aufgerufen werden kann dies mit call bewerkstelligt werden. Oder mit der Methode Function.prototype.apply, welche die Argumente für den Aufruf in Form eines Arrays entgegennimmt.

    Gruß,

    Orlok

    1. Lieber Orlok,

      wo genau können wir diesen Deinen Wiki-Tutorial-Artikel im Wiki einfügen?

      Das nächste Mal vielleicht dieses Posting gleich als Wiki-Artikel an entsprechender Stelle veröffentlichen und hier nur noch darauf verlinken? So á la "hab' mal eben schnell einen Artikel veröffentlicht, der sich als Antwort auf Deine Frage eignet" vielleicht?

      Wow, so viel Schaffenskraft - und dann isses nur ein Forumsposting... das sollte so nicht bleiben!

      Liebe Grüße,

      Felix Riesterer.

      1. Hallo Felix

        Das nächste Mal vielleicht dieses Posting gleich als Wiki-Artikel an entsprechender Stelle veröffentlichen und hier nur noch darauf verlinken?

        Muss ein Déjà-vu sein. Irgendwie habe ich das Gefühl, als hätte ich die Diskussion schonmal geführt.

        Jedenfalls, nicht jeder längere Beitrag hätte alternativ auch als Wiki-Artikel verfasst werden können, und ganz bestimmt nicht dieser spezielle Beitrag. Das ist überhaupt so gut wie nie sinnvoll, denn das würde voraussetzen, dass es im Wiki zufällig eine inhaltliche Lücke gibt, welche sich mit der Thematik der zu gebenden Antwort nahezu vollständig deckt.

        Meist ist es jedoch so, dass die entsprechenden Informationen durchaus (teilweise) vorhanden sind, aber vielleicht auf mehrere Artikel und Abschnitte verteilt. Oder, wenn die Informationen tatsächlich nicht vorhanden sind, wäre es mit Blick auf die Systematik des Wikis womöglich sinnvoll, diese über mehrere Artikel und Abschnitte zu verteilen, sodass es mit einem einzelnen Artikel im Ergebnis nicht getan wäre.

        Darüber hinaus ist das Schreiben einer Antwort hier im Forum kaum mit dem Verfassen eines Artikels für das Wiki zu vergleichen, denn ein Wiki-Artikel erfordert viel gewissenhaftere Arbeit, größeren Bedacht bei jeder Formulierung und überhaupt eine sorgsamere Auswahl der dargestellten Informationen. Das Verfassen eines Wiki-Artikels ist in der Regel also mit ungleich größerem Aufwand verbunden.

        Aber hey, was weiß ich schon vom Artikelschreiben für’s Wiki?

        Wow, so viel Schaffenskraft - und dann isses nur ein Forumsposting... das sollte so nicht bleiben!

        Da hast du allerdings recht. Ich habe tatsächlich schon viele Antworten hier im Forum geschrieben, bei denen ich mir sehr viel Mühe gegeben – und in die ich auch sehr viel Zeit investiert habe. Geholfen habe ich damit aber wohl kaum jemandem; Bloß Kraft und Zeit habe ich verschwendet, die ich anderswo besser hätte einsetzen können. Ich sollte mir solche Antworten in Zukunft also einfach sparen.

        Gruß,

        Orlok

    2. nabend Orlok,

      aaah das mit dem window-Objekt wo this probleme macht. da habe ich, wie mir in SelfHTML empfolen wurde, that = this ausgetauscht. Und das die Variable undefine neu ist war mir auch nicht bewusst. Erst einmal danke für deinen umfangreichen Beitrag.

      Ich muss den Text erstmal verdauem bis ich ihn verstehe.

      Herzliche Grüße MB

  2. Lieber MB,

    wo finde ich hier ein Tutorial für JS Patterns?

    was sind "JS Patterns"? Meinst Du vielleicht reguläre Ausdrücke in JS?

    Liebe Grüße,

    Felix Riesterer.

    1. wo finde ich hier ein Tutorial für JS Patterns? was sind "JS Patterns"? Meinst Du vielleicht [reguläre Ausdrücke]

      Wohl eher sowas wie https://addyosmani.com/resources/essentialjsdesignpatterns/book/

      das habe ich gerade als ersten Googletreffer gefunden und kann die Verständlichkeit der Darstellung nicht beurteilen...

      Hier im Wiki sind die Dinge etwas verteilt, und Orloks Langposting wäre als eigener Beitrag deshalb ein Problem, weil den Artikeln, die es im WIKI gibt, die Systematik fehlt. Der Beitrag an sich ist gut, aber eine Perle von vielen im <übertreibung>JavaScript-Sauhaufen</übertreibung>.

      Rolf

      1. Servus!

        Hier im Wiki sind die Dinge etwas verteilt, und Orloks Langposting wäre als eigener Beitrag deshalb ein Problem, weil den Artikeln, die es im WIKI gibt, die Systematik fehlt. Der Beitrag an sich ist gut, aber eine Perle von vielen im <übertreibung>JavaScript-Sauhaufen</übertreibung>.

        Die anscheinend fehlerhafte oder mangelnde Systematik ist im Laufe der Jahre so gewachsen und war schon öfter Gegenstand von Diskussionen.

        JavaScript/grundlegende Konzepte wurde nach dieser Diskussion "JavaScript im Wiki" durch eine Textübertragung der von Mitleser angesprochenen JavaScript-Dokumentation vom molily ersetzt. Ich habe versucht, sie, soweit es mir möglich war, zu aktualisieren. Danke an @Rolf b, dass er den ersten Artikel überarbeitet.

        @Orlok hat dankenswerterweise die noch fehlenden Artikel zur Ereignisbehandlung und den Objekten Object und Function mit ihren Eigenschaften und Methoden erstellt.


        Ich kann immer wieder nur appellieren:

        • Meldet Fehler und Inkonsistenzen, indem ihr ein {{ToDo}} einfügt.

        • Bessert fehlerhafte Angaben eventuell gleich selbst aus.

        • Macht Vorschläge für eine Umbenennung, Verschiebung und Aufteilung von Seiten.


        Mich frustriert einerseits die pauschale Kritik, die m.E. derjenigen von "in der alten 8.12. habe ich alles gefunden" ähnelt und andererseits die fehlende Resonanz im Selfraum, die uns bewussten Schwächen konkret zu beseitigen. Die spärliche Beteiligung an den von der MV vorgeschlagenen Wiki-Pushes ist da der beste Beweis.

        Herzliche Grüße

        Matthias Scharwies

        --
        Es gibt viel zu tun - packen wir's an: ToDo-Liste gewünschte Seiten
        1. Hallo Matthias,

          ich wollte dich nicht frustrieren. Es ist Wahnsinn, wieviel Arbeit du hier investierst, und leider hat nicht jeder die Energie oder Zeit dafür, um es dir gleichzutun. Und es ist leider auch so, dass das alte selfHtml sehr allein da stand, heute dagegen zumindest das MDN eine verdammt gute Alternative zu selfHtml darstellt. Wenn sogar die Artikel im Wiki dorthin als Referenz verlinken...

          Gruß Rolf

          1. Servus!

            Hallo Matthias,

            ich wollte dich nicht frustrieren. Es ist Wahnsinn, wieviel Arbeit du hier investierst, und leider hat nicht jeder die Energie oder Zeit dafür, um es dir gleichzutun. Und es ist leider auch so, dass das alte selfHtml sehr allein da stand,

            Ja, da ist von 2007- 2010 oder 2014 viel liegengeblieben, was jetzt aber langsam aufgeholt ist.

            heute dagegen zumindest das MDN eine verdammt gute Alternative zu selfHtml darstellt.

            Ja, wobei nicht alles übersetzt ist und viele Artikel seit der Veröffentlichung wohl nicht mehr gepflegt wurden. Gerade beim Browser-Support sind wir mit der Verlinkung auf Caniuse besser dran.

            Wenn sogar die Artikel im Wiki dorthin als Referenz verlinken...

            Haben wir früher nicht gemacht, aber irgendwie sind die MDN-Artikel und die Links auf die Spec doch Mehrwert. Gerade die Wikipedia ist da Vorbild, wie viel Quellen die mittlerweile haben.

            Mir tut's in der Seele weh, dass Stefan Münz die Leute 2003 aufgefordert hatte, doch zur Wikipedia zu gehen und dort was schreiben.

            Herzliche Grüße

            Matthias Scharwies

            --
            Es gibt viel zu tun - packen wir's an: ToDo-Liste gewünschte Seiten
            1. Lieber Matthias,

              Mir tut's in der Seele weh, dass Stefan Münz die Leute 2003 aufgefordert hatte, doch zur Wikipedia zu gehen und dort was schreiben.

              mittlerweile verlinken die in ihren Weblinks auf unser Wiki mit dem Hinweis

              CSS. selfhtml.org, 6. Juni 2014, abgerufen am 24. September 2014 (deutsch, Ausführliche Darstellung zusammen mit HTML).

              Liebe Grüße,

              Felix Riesterer.

    2. nabend Felix,

      wo finde ich hier ein Tutorial für JS Patterns?

      was sind "JS Patterns"? Meinst Du vielleicht reguläre Ausdrücke in JS?

      Liebe Grüße,

      das was Rolf gepostet hat "Design Patterns". Sry wenn der Begriff nicht deutlich geworden ist.

      Herzlichste Grüße MB

      1. Servus!

        wo finde ich hier ein Tutorial für JS Patterns?

        das was Rolf gepostet hat "Design Patterns".

        Ich habe mal

        angelegt und von der einen Stelle, die es schon erwähnt, auch verlinkt. Das wäre aber bestimmt auch einen eigenen Artikel in Programmiertechnik wert.

        Herzliche Grüße

        Matthias Scharwies

        --
        Es gibt viel zu tun - packen wir's an: ToDo-Liste gewünschte Seiten