2016-06-16 10 views
1

Dies ist aufgrund der sich überlappenden Schlüsselsuchbegriffe wirklich schwierig zu finden. Ich habe dieses Schaltspiel, das ich mache. FYI, in Bezug auf Stil, verwende ich Großbuchstaben Namen für Objekte, die, obwohl sie ein wenig ändern können (wie, number_of_boards oder etwas), nicht für andere Dinge wiederverwendet werden, aber die Eigenschaftsnamen werden wiederverwendet (zum Beispiel wenn ich auf der einen Seite meine keltischen Knoten Generator und Schaltungen Spiel hatte, hätte ich KNOT.draw und CIRCUIT_BOARD.draw)Objektkonstruktor als Funktion in einem größeren Objekt

So, hier ist die kurze Version meiner aktuellen Set up:

CIRCUIT_BOARD = { 
    "blankGridSquare": function(){ 
     //Returns brand new object that is one blank grid square of the map 
    } 
    , "blankMap": function(width,height){ 
     //Returns brand new object that has a bunch of blank grid squares 
    } 
    , "copyMap": function(map){ 
     //Returns new object with the same value as parameter map 
    } 
    , "newBoard": function(svg,width,height,ioPlugs,map){ 
     //Returns new object with a target svg, 
     //either a blank map or a copy of the given map, 
     //a set of ioPlugs, 
     //the electric current set up, 
     //etc. 
     //Initializes a few other things 
    } 
    // and other functions of course... 
} 

ich will nicht werde alle Funktionen in eine Variable umwandeln, weil ich die Flexibilität haben möchte, mehrere Spiele auf einer Seite zu platzieren. Ich habe gelesen, dass die korrekte Erstellung von Konstruktoren die Verwendung des Schlüsselwortes this beinhaltet. Aber wenn ich versuche, this für diese Konstruktoren zu verwenden, bekomme ich zum Beispiel eine Karte mit einer Reihe von Funktionen, an denen jeder einzelne gridSquare mit all diesen Funktionen verbunden ist.

Die Frage ist also, wie mache ich mehrere Objektkonstruktoren als nicht instanzgebundene Funktionen, die alle Eigenschaften eines anderen Objekts sind? Ich weiß nicht einmal, ob diese verdichtete Frage richtig formuliert ist.

+2

Wenn Sie 'neue CIRCUIT_BOARD.someFunction()' aufrufen, dann wird der Wert von 'this' in diesem Aufruf ein neues Objekt sein. Wenn Sie 'new' nicht vor dem Aufruf verwenden, ist der Wert von' this' das 'CIRCUIT_BOARD'-Objekt selbst. – Pointy

+0

Also, wenn ich 'neue CIRCUIT_BOARD.blankGridSquare' innerhalb der" blankMap "-Funktion verwenden, sollte es mir nur das beabsichtigte leere Quadrat ohne fremde Funktionen geben? ... Testen Sie jetzt ... – RoboticRenaissance

+0

Vielen Dank, Pointy. Genau das habe ich gebraucht. Beim nächsten Mal sollten Sie Informationen wie diese in eine Antwort einfügen. Ich hätte es akzeptiert, sobald ich es getestet hatte. – RoboticRenaissance

Antwort

2

Dies ist das genaue Muster, das Module verwenden. Zum Beispiel:

export function FooCtor() { 
    this.stuff = 3; 
} 

wird geworden:

exports.FooCtor = FooCtor; 
function FooCtor() { 
    this.stuff = 3; 
} 

Einschließlich Konstrukteuren in einem Objekt (die nur Funktionen sind) keine Probleme verursachen.

Die Verwirrung, in die Sie laufen, as Pointy mentioned, ist um das, was der new Operator zu this innerhalb eines Funktionsaufrufs macht. Wenn Sie new für eine Funktion aufrufen, die vernünftigerweise als Konstruktor fungieren kann, erstellt die Laufzeitumgebung einen neuen Kontext mit dem meist leeren Objekt, das this zugewiesen ist, und ruft die Funktion damit auf. Es ist nicht ganz im Gegensatz zu tun:

newInstance = FooCtor.call({}, ...args) 

die Spezifikation Arbeiten durch um herauszufinden, warum, was geschieht:

Beginnend mit §12.3.3 der Spezifikation (der new Operator), heißt es:

MemberExpression: neuMemberExpressionArgumente

  1. Return EvaluateNew (Member, Argumente).

EvaluateNew führt uns zu §12.3.3.1.1, wo 3-4 sagen Schritte:

Lassen ref das Ergebnis der Auswertung constructProduction. Lassen Sie Konstruktor GetValue sein (ref).

die ihren Weg nach unten durch jede Kette von Eigenschaftenaccessoren arbeiten (foo.bar, foo[bar], was auch immer). Als nächstes wird Schritt 9 des gleichen Abschnitts sagt:

Return Baukonstruktion (Konstruktor, argList).

Führt zu und das interne Verhalten des Bauprozesses.

Beachten Sie, dass 9 von EvaluateNew Schritt tut nicht geben Sie die newTarget Parameter Construct, den Schritt 1 in Construct auslöst:

Wenn newTarget nicht bestanden wurde, lassen newTarget seinesF .

Schritt 5 von Construct Händen Ausführung weg, um die [[Construct]] Eigenschaft Konstruktor, bei §9.2.2 definiert. Schritt 8 Zustände:

Wenn Art ist "base", führen OrdinaryCallBindThis (F, calleeContext, thisArgument).

So spulen wir auf die Definition von thisArgument in 5.a:

Lassen thisArgument OrdinaryCreateFromConstructor (newTarget, "% ObjectPrototype%") sein.

Was uns zu §9.1.14 springt nach oben, die tatsächlich (endlich) geht über das neue Objekt zu schaffen, um für den Konstruktor als Kontext verwendet werden:

Die abstrakte Operation OrdinaryCreateFromConstructor schafft ein gewöhnliches Objekt, das [[ Prototyp]] Der Wert wird aus der Prototypeigenschaft eines Konstruktors abgerufen, sofern sie existiert. Andernfalls wird der intrinsicDefaultProto genannte intrinsic für [[Prototype]] verwendet.

An dieser Stelle sind wir weit entfernt davon, wie auf die Konstruktorfunktion zugegriffen wurde. new ist es egal, solange es eine Funktion bekommt, die als Konstruktor sinnvoll ist. Wenn Sie ihm eine sinnvolle Funktion gegeben haben, richtet diese Kette nur ein neues Objekt ein und verarbeitet alle Prototyp-Verbindungselemente.

+0

Uh, das ist ziemlich verwirrend. Aber was läuft darauf hinaus, dass das Schlüsselwort 'new' den Verweis auf das Schlüsselwort' this' in der Funktion ändert? Es entfernt die Funktion aus ihrem Kontext und gibt ihr einen neuen Kontext? So ähnlich? Es gibt einen Grund, warum ich seit Jahren w3schools über MDN benutzt habe ... – RoboticRenaissance

+0

Ich habe ein bisschen eine Zusammenfassung hinzugefügt, bevor ich den Teil durch die Spezifikation gehe. Die Spezifikation kann schwer zu folgen sein, aber wenn Sie es wie Code lesen, fängt es an, viel Sinn zu machen. * Bitte * benutze keine w3schools; Sie neigen dazu, sachlich falsch zu sein, und ihre Beispiele haben viele Probleme. – ssube

+0

Ich finde, dass ihnen einfach einige der komplexeren Informationen fehlen. Wenn ich zum Beispiel alle Dinge finden möchte, die ich mit SVG erstellen kann, gehe ich stattdessen zu MDN. Es ist eher eine Einführung in jede der verschiedenen Sprachen und Sachen. Ich habe noch nie ein konkretes Beispiel dafür gesehen, dass da etwas eklatant falsch ist. Aber selbst wenn es da ist, verursacht das Missverständnis, das neuere Zielgruppen auf sachlich korrekteren Seiten haben, viel mehr Probleme als direkte falsche Antworten. Zumindest war das meine Erfahrung, als ich jünger war. Ich kann jetzt die JQuery API und MDN Sachen jetzt lesen, also bevorzuge ich das. – RoboticRenaissance

Verwandte Themen