2016-03-26 9 views
1

Also habe ich mit der prototypischen Vererbung in CoffeeScript gespielt, und insbesondere mit dem Schreiben von CoffeeScript-Klassen, die von einem bestimmten Objekt erben, eher als eine andere Klasse, ähnlich der Objektfunktion von Crockford. Im Wesentlichen möchte ich eine Klasse schreiben, die von einem bestimmten Objekt erben kann, das an ihren Konstruktor übergeben wird. Leider glaube ich, dass dies unmöglich sein kann ohne auf setPrototypeOf zurückzugreifen, was ich angesichts der ziemlich alarmierenden Warnungen lieber nicht tun würde. Stattdessen werde ich mich wahrscheinlich mit einer Funktion begnügen, die etwas Ähnliches tun kann. Im Folgenden sind zwei Möglichkeiten:Utility-Funktionen zum Instantiieren einer Instanz einer CoffeeScript-Klasse, die ein bereits existierendes Objekt erweitert

a = {foo: 1} 

class Example 
    constructor: (@bar) -> 

extendObject = (parent, Class, args...) -> 
    F = (anon...) -> Class.apply(@, anon) 
    F:: = Object.create parent 
    F::constructor = Class 
    new F args... 

extendObjectMaker = (parent, Class) -> 
    F = (anon...) -> Class.apply(@, anon) 
    F:: = Object.create parent 
    F::constructor = Class 
    F 

maker = extendObjectMaker a, Example 

test1 = extendObject a, Example, 2 
test2 = new maker 2 

Nun, ich den zweiten Ansatz stark bevorzugen, da im Wesentlichen, was es ist eine neue Klasse zurückgibt, die Sie dann mit regelmäßiger Konstruktor Syntax verwenden können. Es gibt nur ein Problem: Während Objekte, die mit erstellt wurden, korrekt als Example s identifiziert werden, werden Objekte, die mit dem von extendObjectMaker zurückgegebenen Konstruktor erstellt wurden, als F s identifiziert und sind keine Instanzen von Example.

console.log test1 instanceof Example # True 
console.log test2 instanceof Example # False 

Da diese Funktionen fast genau den gleichen Code verwenden, ich Schwierigkeiten haben, nur herauszufinden, warum sie ein anderes Verhalten sind aufweisen. Also, weiß jemand, warum test2 nicht als Example angezeigt wird, und was ich ändern muss, um es zu tun?

+0

Scheint, wie Sie dies nicht auf der richtigen Webseite sind :) – Ven

+0

Uh, warum sollte das sein? – rmehlinger

+1

Oh mein Gott, es tut mir so leid! Stackoverflow auf Handy hat das Farbschema einer anderen Stackexchange-Website! – Ven

Antwort

2

Werfen Sie einen Blick auf den CoffeeScript-Quellcode: http://coffeescript.org/v1/annotated-source/nodes.html#section-60.

CoffeeScript behandelt Konstruktoraufrufe unterschiedlich, je nachdem, ob sie mit einem Splat (args...) oder ohne einen aufgerufen werden.

Ihr Code wird das gewünschte Ergebnis geben, wenn Sie entweder die extendObjectMaker mit new maker [2]...oder aufrufen neu schreiben Ihre Funktion wie folgt:

extendObjectMaker = (parent, Class) -> 
    F = (anon...) -> Class.apply(@, anon) 
    F:: = Object.create parent 
    F::constructor = Class 
    (args...) -> new F args... 
+0

Leider ist die Verbindung jetzt tot –

+1

Aktualisiert! Beachten Sie, dass dies nur für CoffeeScript 1.x relevant ist - nicht sicher, wie CoffeeScript 2 verschiedene Konstruktoraufrufe behandeln würde. –

Verwandte Themen