Freecodecamp: & bgr; QS des Abschnitts Objektorientierte Programmierung

Erstellt am 30. Jan. 2017  ·  44Kommentare  ·  Quelle: freeCodeCamp/freeCodeCamp

Dies wurde ursprünglich für eine bestimmte Herausforderung geöffnet, aber in diesem Abschnitt wurden einige andere Dinge auf dem Weg bemerkt, sodass sie in dieser einen Ausgabe nur konsolidiert werden (jeweils ein Kommentar). @HKuz , wenn es vielleicht schon ein anderes Problem dafür gibt,

Insgesamt finde ich diese Herausforderungen großartig! Auf jeden Fall eine wesentliche Verbesserung gegenüber dem bestehenden OOP-Bereich !!!! Gut gemacht an alle, die sie erschaffen haben !!

Allgemeine Kommentare / Probleme:

  • Es scheint, dass Sie in diesem Abschnitt, sobald Sie eine Herausforderung gelöst haben, den Code ändern oder sogar löschen können und die Herausforderung weiterhin besteht. Ich habe ein separates Problem dafür erstellt: # 13021
  • Es wäre schön, wenn die Ausgaben in der eingebetteten Challenge-Konsole protokolliert würden, damit die Benutzer die Ergebnisse ihres Codes sehen können. Wir rufen häufig Methoden auf, die bei diesen Herausforderungen Dinge in der Konsole protokollieren, aber sie sind nicht dafür ausgelegt, sich in der In-Page-Konsole anzumelden.

Hilfreichster Kommentar

Verwenden Sie Vererbung, damit Sie sich nicht wiederholen :

Diese Herausforderung finde ich etwas verwirrend. Der Titel bezieht sich auf Vererbung, jedoch wird Vererbung in der Herausforderung nie erwähnt - ich erkenne, dass sie mit der nächsten Herausforderung zusammenhängt, sodass Camper schnell herausfinden werden, aber die Art und Weise, wie sie präsentiert wird, ist immer noch etwas abstoßend. Außerdem haben wir am Ende der Herausforderung einen Supertyp Animal , aber wir sind ein wenig verwirrt, da Animal zu diesem Zeitpunkt nicht an Cat und Dog . Um die Verwirrung ein wenig zu unterdrücken, denke ich, dass wir eine kleine Änderung vornehmen könnten:

Dieser Satz stammt aus der nächsten Herausforderung:

Diese und die nächste Herausforderung werden behandeln, wie die Methoden von Animal in Bird and Dog wiederverwendet werden können, ohne sie erneut zu definieren. Es verwendet eine Technik namens Vererbung.

Vielleicht kann, um die Dinge zusammenzubinden, stattdessen eine ähnliche übergeordnete Übersicht in dieser Herausforderung gegeben werden, die alle drei miteinander verbindet, so dass es sich um eine Sequenz handelt, und tatsächlich das Konzept einführt, nach dem die Herausforderung betitelt ist, und es macht klar, dass wir am Ende dieser Herausforderung noch nicht fertig sind.

Alle 44 Kommentare

Verwenden Sie die Punktnotation, um auf die Eigenschaften eines Objekts zuzugreifen

(IN STAGING ENTSCHLOSSEN) ✅

Diese Herausforderung akzeptiert nur Folgendes als Lösung:

console.log(dog.name);
console.log(dog.numLegs);

Wir geben jedoch nicht ausdrücklich an, dass 2 separate Anweisungen verwendet werden sollten, und Folgendes wird nicht bestanden:

console.log(dog.name, dog.numLegs);

Ich denke, wir sollten entweder angeben, dass zwei separate console.log() -Anweisungen gemacht werden müssen, oder den Test umgestalten, um beide Lösungen zu akzeptieren - ich denke, ich würde die letztere Option bevorzugen. Gedanken?

Überprüfen Sie den Konstruktor eines Objekts mit der folgenden Instanz :

(IN STAGING ENTSCHLOSSEN) ✅

  • Aus irgendeinem Grund gibt der Linter die Warnung Expected an assignment of function call and instead saw an expression wenn die richtige Lösung myHouse instanceof House; geschrieben ist. Die Herausforderung ist jedoch vorbei.
  • Außerdem enthält der Seed-Code selbst beim Laden eine Linter-Warnung für ein fehlendes Semikolon.
  • Schließlich bin ich mir nicht sicher, ob es beabsichtigt ist, aber es könnte ein wenig verwirrend sein - in früheren Herausforderungen in diesem Abschnitt sind Konstruktoren wie folgt definiert:
function House(numBedrooms) {
  this.numBedrooms = numBedrooms;
}

Bei dieser Herausforderung wechseln sie jedoch zu dieser Syntax:

let House = function(numBedrooms) {
  this.numBedrooms = numBedrooms;
}

Dies ist weniger ein Problem als vielmehr eine mögliche Quelle der Verwirrung. Wenn wir beide Methoden verwenden, sollten wir den Unterschied meines Erachtens besonders beachten. Andernfalls sollten Sie die Syntax im gesamten Abschnitt konsistent halten. Wahrscheinlich ist es eine gute Idee, beides einzuführen, obwohl ich denke.

Eigene Eigenschaften verstehen :

Nur eine Beobachtung zu diesem Thema und neugierig zu sehen, was andere Meinungen sind - aber diese Herausforderung scheint sich eher um for...in als um hasOwnProperty zu drehen, und for...in ist es nicht in diesem Abschnitt noch ausreichend erklärt.

Wenn wir davon ausgehen, dass die Leute den Rest des Lehrplans durchgearbeitet haben, denke ich, dass dies in Ordnung ist, da dies zumindest im Abschnitt Grundlegende Datenstrukturen behandelt wird, aber wenn wir beabsichtigen, dass die Abschnitte unabhängig voneinander sind und keine Voraussetzungen erfordern als Vielleicht möchten wir das noch einmal überdenken.

Verstehen Sie die Konstruktoreigenschaft :

(IN STAGING ENTSCHLOSSEN) ✅

Diese Herausforderung wird mit beiden Lösungen bestehen:

function joinDogFraternity(candidate) {
  if (candidate instanceof Dog) {
    return true;
  }
  return false;
}

// OR:

function joinDogFraternity(candidate) {
  if (candidate.constructor === Dog) {
    return true;
  }
  return false;
}

Ich sehe dies nicht als ein großes Problem an, da der Instinkt vorschreibt, dass die Leute zuerst die ihnen vorgeschlagene Lösung ausprobieren werden. Ich kann jedoch auch sehen, dass dies ein Problem ist, das auf der ganzen Linie geöffnet wird, wenn ein versierter Camper es in beide Richtungen versucht und will weisen Sie darauf hin.

Wir könnten einfach einen Testfall hinzufügen, der "message: 'your solution should use the constructor property'" sagt, und mit einem regulären Ausdruck überprüfen.

Verwenden Sie Vererbung, damit Sie sich nicht wiederholen :

Diese Herausforderung finde ich etwas verwirrend. Der Titel bezieht sich auf Vererbung, jedoch wird Vererbung in der Herausforderung nie erwähnt - ich erkenne, dass sie mit der nächsten Herausforderung zusammenhängt, sodass Camper schnell herausfinden werden, aber die Art und Weise, wie sie präsentiert wird, ist immer noch etwas abstoßend. Außerdem haben wir am Ende der Herausforderung einen Supertyp Animal , aber wir sind ein wenig verwirrt, da Animal zu diesem Zeitpunkt nicht an Cat und Dog . Um die Verwirrung ein wenig zu unterdrücken, denke ich, dass wir eine kleine Änderung vornehmen könnten:

Dieser Satz stammt aus der nächsten Herausforderung:

Diese und die nächste Herausforderung werden behandeln, wie die Methoden von Animal in Bird and Dog wiederverwendet werden können, ohne sie erneut zu definieren. Es verwendet eine Technik namens Vererbung.

Vielleicht kann, um die Dinge zusammenzubinden, stattdessen eine ähnliche übergeordnete Übersicht in dieser Herausforderung gegeben werden, die alle drei miteinander verbindet, so dass es sich um eine Sequenz handelt, und tatsächlich das Konzept einführt, nach dem die Herausforderung betitelt ist, und es macht klar, dass wir am Ende dieser Herausforderung noch nicht fertig sind.

Verhalten von einem Supertyp erben :

(IN STAGING ENTSCHLOSSEN) ✅

Super kleines Problem hier - ein Teil des Keims dafür lautet wie folgt:

// Add your code below this line

let duck
let beagle

duck.eat(); // Should print "nom nom nom"
beagle.eat(); // Should print "nom nom nom"

Dies löst einen Linterfehler aus. Ich würde stattdessen Folgendes vorschlagen:

Super kleines Problem hier - ein Teil des Keims dafür lautet wie folgt:


let duck; // change this line
let beagle; // change this line

duck.eat(); // Should print "nom nom nom"
beagle.eat(); // Should print "nom nom nom"

@ no-stack-dub-sack - das sind alles großartige Punkte, und ich habe keine Probleme für diesen Abschnitt gesehen, obwohl ich gestern einen Teil offline war. Vielen Dank, dass Sie diesen Abschnitt so ausführlich durchgearbeitet haben. 👍 Hier sind meine Gedanken (tl; dr - ich stimme mit allem überein, was Sie angesprochen haben):

  • Use Dot Notation to Access the Properties of an Object : Tests sollten bestanden werden, wenn jemand eine console.log -Anweisung verwendet.
  • Verify an Object's Constructor with instanceof : Wir sollten das fehlende Semikolon reparieren und konsistent darüber sein, wie House definiert ist. Während es in JS mehrere Möglichkeiten gibt, Dinge zu tun, müssen die Leute nicht verwirrt werden, wenn sie dies zum ersten Mal lernen.
  • Understanding Own Properties : In Bezug auf die for...in wir im Allgemeinen der Ansicht, dass es in Ordnung ist, Konzepte zu verwenden, die bereits im Lehrplan enthalten sind. Camper können herumspringen, wie sie wollen, aber es gibt einen Fluss zu den Themen. (Andernfalls können sich Herausforderungen lang / wiederholen, wenn sie die Dinge neu behandeln müssen, bevor sie auf den Punkt kommen.) Trotzdem denke ich, dass es hilfreich sein kann, direkt unter dem Beispiel eine Notiz einzufügen, in der die Syntax kurz erläutert wird ("Denken Sie daran, dass for...in ...").
  • Understand the Constructor Property : Stimmen Sie Ihrem Punkt zu, indem Sie den Konstruktor in den Anweisungen verwenden
  • Use Inheritance So You Don't Repeat Yourself : Ja, gute Punkte, um die Herausforderungen besser miteinander zu verbinden
  • Inherit Behaviors from a Supertype : Wir sollten auf jeden Fall die Semikolons hinzufügen, und die Kommentare sind auch hilfreich

Lassen Sie mich wissen, ob Sie daran arbeiten möchten - ich springe in einen anderen Abschnitt (könnte in ein oder zwei Tagen daran arbeiten), oder wir könnten dies als gewünschte Hilfe öffnen 😄

@HKuz Cool, danke! Ich werde den Abschnitt beenden, ein paar weitere Kommentare hinzufügen, wenn ich welche habe, und dann können wir an diesem Punkt entscheiden, aber ich denke, es wird wahrscheinlich am besten sein, ihn für Help Wanted zu öffnen. Sie auf dem Laufenden halten.

Methoden nach Vererbung hinzufügen :

Diese Herausforderung ist aufgrund des folgenden Testfalls etwas verwirrend:

Dog should have the bark() method as an own property.

Die Lösung für diesen Teil sucht danach:

Dog.prototype.bark = function() {
    console.log('Woof!');
};

und während Dog.prototype.hasOwnProperty('bark') true zurückgibt (das ist natürlich richtig), kommt die Quelle der Verwirrung von hier (die von
image

Mit den Informationen, die Camper bis zu diesem Punkt erhalten, würden sie wahrscheinlich annehmen, dass sie, um diesen Test zu bestehen, die bark -Methode direkt auf der Objektinstanz von Dog definieren müssten und nicht auf dem Prototyp.

Der Unterschied besteht darin, dass für Instanzen von Dog bark keine own Eigenschaft wäre, sondern dass es sich um eine own Eigenschaft von Dog.prototype . Das ist etwas verwirrend für jemanden, der gerade erst in diese Konzepte eingeführt wird.

Die einfachste Lösung wäre, den Testfall so zu ändern, dass er sagt:

Dog.prototype should have the bark() method as an own property.

Obwohl vielleicht eine kurze Erklärung ist, um Camper wissen zu lassen, dass eine prototype -Eigenschaft eines Prototyps tatsächlich eine own -Eigenschaft dieses Prototyps ist? Wow, das ist ein Zungenbrecher, also ja, es ist ein bisschen verwirrend, und ich bin mir nicht sicher, wie ich diese Verwirrung am besten lindern kann ...

Verwenden Sie Closure, um Eigenschaften innerhalb eines Objekts vor externen Änderungen zu schützen :

(IN STAGING ENTSCHLOSSEN) ✅

Kleiner Tippfehler:

image

Ich denke, es sollte "... außerhalb der Definition von bird " liegen. ?

Verstehen Sie den sofort aufgerufenen Funktionsausdruck (IIFE) :

Keine größeren Probleme mit dieser Herausforderung - nur ein Vorschlag - obwohl mir klar ist, dass anonyme IIFE das häufigste Muster sind (und das Muster, das in der nächsten Herausforderung verwendet wird), ist hier vielleicht ein guter Ort, um dieses IIFE zu erwähnen IIFE schwerer zu finden sind

Gedanken?

Verwenden Sie ein IIFE, um ein Modul zu erstellen :

Ich würde gerne ein paar Gedanken dazu bekommen ... vielleicht @dhcodes oder @Greenheart?
Mein Problem ist, dass ich nicht der Meinung bin, dass die Herausforderung angemessen erklärt, warum ein IIFE in diesem Szenario sinnvoll ist.

Die Lösung erfordert:

let funModule = (function() {
  return {
    isCuteMixin: function(obj) {
      obj.isCute = function() {
        return true;
      };
    },  
    singMixin: function(obj) {
      obj.sing = function() {
        console.log("Singing to an awesome tune");
      };
    }
  };
})();

Sie können also Folgendes tun:

function Bird () { }
let duck = new Bird();
funModule.singMixin(duck);
duck.sing();

Sie können jedoch dasselbe auf weniger ausführliche Weise und ohne Aufrufen einer Funktion erreichen, indem Sie einfach das Objekt definieren, das IIFE zurückgibt.

Die Herausforderung lautet:

Der Vorteil des Modulmusters besteht darin, dass alle Bewegungsverhalten in ein einzelnes Objekt gepackt werden können, das dann von anderen Teilen Ihres Codes verwendet werden kann.

Da dies jedoch überhaupt kein IIFE erfordert, würde ich wahrscheinlich die Idee in Frage stellen, das Konzept hier einzuführen oder einen stärkeren Weg zu finden, um es zu verknüpfen. Dies könnte verwirrend / irreführend sein, da Camper glauben, dass sie dies tun MÜSSEN Erreichen Sie dieses Muster, wenn dies nicht der Fall ist.

Irgendwelche Gedanken?

@ no-stack-dub-sack Ich stimme zu, dass dies nicht das beste Beispiel für ein IIFE ist. Wäre es besser, wenn wir als Beispiel module angeben?

Ich denke, der Kernwert des IIFE besteht darin, dass Sie private Eigenschaften und Methoden Ihrer Objekte erstellen können. Dies ist sehr nützlich, um die Art und Weise zu verringern, in der andere Ihre Software (falsch) verwenden können, in der Hoffnung, dass dadurch die Zuverlässigkeit erhöht wird.

Beispielsweise haben Sie möglicherweise ein kleines Dienstprogrammmodul für Ihre Vanilla JS-Anwendung, in dem Sie nur einige öffentliche Methoden verfügbar machen möchten, da der Rest geändert / entfernt werden soll und Probleme verursachen würde, wenn sie in anderen Teilen der Codebasis verwendet werden.

Diese Seite hat viele gute Beispiele: https://toddmotto.com/mastering-the-module-pattern/

@Greenheart Nun, in der letzten der 2 IIFE-Herausforderungen hier wird es als Modulmuster eingeführt, und ich habe kein Problem damit, ich denke nur, es könnte klarer erklärt werden, warum ein IIFE verwendet wird und dass ein IIFE muss nicht unbedingt vorhanden sein, um die gleiche Funktionalität zu erreichen. Ich denke, das sagt alles:

Der Kernwert des IIFE besteht darin, dass Sie private Eigenschaften und Methoden Ihrer Objekte erstellen können. Dies ist sehr nützlich, um die Art und Weise zu verringern, in der andere Ihre Software (falsch) verwenden können, in der Hoffnung, dass dadurch die Zuverlässigkeit erhöht wird.

Wenn wir dies nur erklären und den Benutzer wissen lassen können "Sie können dieselbe Funktionalität ohne IIFE erreichen, aber mit einem IIFE ist ein besserer Weg, und hier ist der Grund ...".

Die aktuellen Anweisungen sagen:

Ein sofort aufgerufener Funktionsausdruck (IIFE) wird häufig verwendet, um verwandte Funktionen in einem einzelnen Objekt oder Modul zu gruppieren.

Fügen wir dazu einfach hinzu: "Während die gleiche Funktionalität ohne IIFE erreicht werden kann, besteht der Kernwert des IIFE in diesem Zusammenhang darin, dass Sie private Eigenschaften und Methoden Ihrer Objekte erstellen können. Dies kann sehr nützlich sein, um die zu verringern." Möglichkeiten, wie andere Ihre Software (falsch) verwenden und die Dinge viel zuverlässiger machen können. "

@ no-stack-dub-sack Das! :aufzeigen:

Ich habe mir die Freiheit genommen, es zu kompilieren und einige kleinere Änderungen vorzunehmen. So etwas brauchen wir: erröten:
An <dfn>immediately invoked function expression</dfn> (IIFE) is often used to group related functionality into a single object or module. While the same functionality can be achieved without an IIFE, its core value in this context is that you can create private properties and methods for your objects. This can be very useful for decreasing the ways others can (mis)use your software, and make things much more reliable.

Verwenden Sie möglicherweise <dfn> wenn der Begriff in früheren Herausforderungen nicht verwendet wurde.

Ich werde fortfahren und die Tests für " Punktnotation verwenden" aktualisieren, um

Fahren Sie mit https://github.com/freeCodeCamp/freeCodeCamp/issues/12966#issuecomment -275974706 fort.

Das erste Problem ist, dass der Linter nicht möchte, dass wir einen Ausdruck schreiben, der im Wesentlichen toter Code ist (da wir weder eine Funktion aufrufen noch eine Variable erstellen). Um dies zu beheben, schlage ich vor, das Ergebnis einer Variablen zuzuweisen.

Das zweite und dritte Problem kann behoben werden, indem der Startwert geändert wird, um den von Ihnen vorgeschlagenen Code zu verwenden. Das Zuweisen von Funktionsobjekten zu Variablen kann entweder an einer anderen Stelle oder durch Erfahrung vermittelt werden. Ich denke, wir sollten mit function X () {} übereinstimmen

Ich werde das beheben: Lächeln:

Mir ist aufgefallen, dass keine Herausforderung Lösungen hat, deshalb arbeite ich derzeit an einer PR.

Eigene Eigenschaften verstehen :

(IN STAGING ENTSCHLOSSEN) ✅

Die Tests erlauben derzeit die Verwendung der eingebauten Methode Object.keys() , aber ich denke, Camper erhalten bessere Übungen, indem sie for...in Kombination mit Object.hasOwnProperty() .

Objektorientierte Programmierung: Über alle Eigenschaften iterieren :

(IN STAGING ENTSCHLOSSEN) ✅

Ich habe gerade festgestellt, dass diese Herausforderung das gleiche Problem hat - sie ermöglicht die Verwendung von Object.keys() Da ich immer noch nicht der Meinung bin, dass dies bei diesen Herausforderungen zulässig sein sollte, werde ich eine PR erstellen, die den Testfall aus dieser Zeile hinzufügt

function Dog(name) {
  this.name = name;
}

Dog.prototype.numLegs = 4;

let beagle = new Dog("Snoopy");

let ownProps = Object.keys(beagle);
let prototypeProps = Object.keys(Dog.prototype);

Das sofort beheben: Lächeln:

Objektorientierte Programmierung: Ändern Sie den Prototyp in ein neues Objekt

Unzureichende Anweisungen und Tests. Sollten describe und eat nur auf dem prototype , oder sollten sie Funktionen sein?

Ich denke, wir sollten Tests hinzufügen, um zu überprüfen, ob es sich um Funktionen handelt.

Objektorientierte Programmierung: Denken Sie daran, die Konstruktoreigenschaft beim Ändern des Prototyps festzulegen

PR eingereicht: white_check_mark:

Diese Herausforderung sollte wahrscheinlich "Konstruktoreigenschaft" als <code>constructor</code> property formatieren, um die Lesbarkeit und Konsistenz zu verbessern. Was denken Sie?

Beispielsweise verwendet die Testnachricht dieses Format.

Ein allgemeiner Vorschlag ist, dass wir let -Anweisungen durch const ersetzen, um Best Practices zu zeigen. Dieses Video von @mpj erklärt es gut!

Objektorientierte Programmierung: Zurücksetzen einer geerbten Konstruktoreigenschaft :

PR Eingereicht: white_check_mark:

Kleiner Tippfehler: supertype's sollte wahrscheinlich supertype

Objektorientierte Programmierung: Verwenden Sie ein IIFE, um ein Modul zu erstellen :

PR eingereicht: white_check_mark:

Kleiner Tippfehler: "Hier ist ein Beispiel, das es verwendet:" sollte in "Hier ist ein Beispiel, das es verwendet:" geändert werden.

Ein weiterer allgemeiner Vorschlag: Ich denke, wir müssen die Beispiele ändern, damit Camper das Beispiel nicht einfach kopieren und 1-2 Dinge ändern können, um die Herausforderung abzuschließen.

Die Beispiele sollten das Konzept zeigen, aber keine Eigenschaften oder Methoden verwenden, die von der Herausforderung selbst verwendet werden. Auf diese Weise werden die Menschen meiner Meinung nach aus jeder Herausforderung mehr lernen.

Ditch Custom CSS für Bootstrap

Am Samstag, 4. Februar 2017, um 21:11 Uhr, Samuel Plumppu [email protected]
schrieb:

Ein weiterer allgemeiner Vorschlag: Ich denke, wir müssen die Beispiele so ändern
Camper können nicht einfach das Beispiel kopieren und 1-2 Dinge ändern, um das zu vervollständigen
Herausforderung.

Die Beispiele sollten das Konzept zeigen, jedoch keine Eigenschaften oder Methoden verwenden
die von der Herausforderung selbst genutzt werden. Ich denke, auf diese Weise werden die Leute lernen
mehr von jeder Herausforderung.

- -
Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/freeCodeCamp/freeCodeCamp/issues/12966#issuecomment-277463832 ,
oder schalten Sie den Thread stumm
https://github.com/notifications/unsubscribe-auth/AX9USApjW3rwocbHWe2yoFLV0RegbkCCks5rZL9SgaJpZM4LxApU
.

@iansibindi Es sieht so aus, als https://github.com/freecodecamp/freecodecamp und klicken Sie oben rechts auf

Entschuldigung für die Unannehmlichkeiten!

@Greenheart Ich

Ich werde mit einer ersten Überprüfung der PRs beginnen, aber glauben Sie, Sie könnten jedem der ursprünglichen Kommentare einen Kommentar hinzufügen, wenn für sie eine PR geöffnet ist, damit wir nachverfolgen können, welche Probleme behoben wurden?

@ no-stack-dub-sack Haha Ich muss zugeben, dass ich es auch nicht selbst verfolgen kann, ich habe einfach weiter gepostet! :Lächeln:

Ich werde am Anfang jedes Kommentars, der WIP / behoben ist, ein großes "PR open" (mit Link dazu) hinzufügen.

@ Greenheart Perfekt! Vielen Dank! Ich habe die ersten PRs überprüft

@ no-stack-dub-sack Okay, noch ein paar Dinge zu tun, aber ich habe heute einige davon gelöst!

Ups, schloss es wieder: lachend:

@ Greenheart Whoa! Ein Rückschritt - gibt es in diesem noch etwas zu tun? Einige wichtige Verbesserungen wurden vorgenommen!

@ no-stack-dub-sack Ich weiß nicht - es gibt noch einige Dinge zu tun, die den obigen Kommentaren entsprechen, aber sie könnten an anderen Stellen gelöst worden sein?

Ich denke, es ist noch nicht behoben. Lassen Sie mich wissen, wenn Sie anders denken

Tolle Arbeit an alle. Ich schließe dieses Problem und wir können spezifischere Probleme wieder öffnen, sobald sie auftauchen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen