Auf Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
würde kompilieren zu:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
Das Kompilieren über ein Kaffeeskript unter node.js umschließt Folgendes:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Die Ärzte sagen:
Wenn Sie Variablen der obersten Ebene für andere zu verwendende Skripts erstellen möchten, hängen Sie sie als Eigenschaften im Fenster oder im Exportobjekt in CommonJS an. Mit dem existenziellen Operator (siehe unten) können Sie zuverlässig herausfinden, wo Sie sie hinzufügen können, wenn Sie sowohl auf CommonJS als auch auf den Browser abzielen: root = exportiert? diese
Wie definiere ich dann globale Variablen in CoffeeScript? Was bedeutet "sie als Eigenschaften im Fenster anhängen"?
javascript
coffeescript
Handweberei
quelle
quelle
window
Objekt oder demexports
Objekt gespeichert werden . Es müssen keine globalen Variablen erstellt werden.window
(oderglobal
auf nodejs) ObjektsAntworten:
Da das Kaffeeskript keine
var
Anweisung enthält, fügt es diese automatisch für alle Variablen im Kaffeeskript ein. Auf diese Weise wird verhindert, dass die kompilierte JavaScript-Version alles in den globalen Namespace verliert .Da es also keine Möglichkeit gibt, absichtlich etwas von der Kaffeeskript-Seite in den globalen Namespace zu "lecken" , müssen Sie Ihre globalen Variablen als Eigenschaften des globalen Objekts definieren .
Dies bedeutet, dass Sie etwas tun müssen
window.foo = 'baz';
, das den Browser-Fall behandelt, da dort das globale Objekt das istwindow
.Node.js
In Node.js gibt es kein
window
Objekt, sondern dasexports
Objekt, das an den Wrapper übergeben wird, der das Node.js-Modul umschließt (siehe: https://github.com/ry/node/blob/master/src/node.js#) L321 ), also müssten Sie in Node.js Folgendes tunexports.foo = 'baz';
.Lassen Sie uns nun einen Blick darauf werfen, was in Ihrem Zitat aus den Dokumenten steht:
Dies ist offensichtlich ein Kaffeeskript, also schauen wir uns an, was dies tatsächlich kompiliert:
Zuerst wird geprüft, ob dies
exports
definiert ist, da der Versuch, auf eine nicht vorhandene Variable in JavaScript zu verweisen, andernfalls einen SyntaxError ergeben würde (außer wenn er mit verwendet wirdtypeof
).Wenn also
exports
vorhanden ist, was in Node.js (oder in einer schlecht geschriebenen WebSite ...) der Fall ist, verweist root aufexports
, andernfalls aufthis
. Also was istthis
?Wenn Sie
.call
eine Funktion verwenden, wird dasthis
Innere der Funktion an den ersten übergebenen Parameter gebunden. Wenn der Browserthis
nun daswindow
Objekt ist, ist Node.js der globale Kontext, der auch alsglobal
Objekt verfügbar ist .Da Sie die
require
Funktion in Node.js haben, müssen Sie demglobal
Objekt in Node.js nichts zuweisen , sondern demexports
Objekt zuweisen, das dann von derrequire
Funktion zurückgegeben wird.Kaffee-Skript
Nach all dieser Erklärung müssen Sie Folgendes tun:
Dadurch wird unsere Funktion
foo
im globalen Namespace deklariert (was auch immer das sein mag).Das ist alles :)
quelle
global
,GLOBAL
undroot
Objekten in node.js?ReferenceError
?(exports ? this).foo = -> 'Hello World'
global = exports ? this
. Die Behauptung, dass "im Fall von Node.js der globale Kontext wäre ..." falsch ist, weil diethis
Variable, wenn sie von node.js benötigt oder ausgeführt wird, als Modulbereich ausgewertet wird. Wenn Sie also erwarten, dass das Einstellen von Requisiten weltweit verfügbar ist, werden Sie enttäuscht sein. Wenn Sie Dinge global im Kontext von node.js festlegen möchten, müssen Sie dieglobal
Variable anstelle von verwendenthis
.Mir scheint, @atomicules hat die einfachste Antwort, aber ich denke, es kann ein bisschen mehr vereinfacht werden. Sie müssen
@
vor allem, was global sein soll, ein setzen, damit es auf das globale Objekt kompiliertthis.anything
und auf diesesthis
verweist.damit...
kompiliert zu ...
und funktioniert innerhalb und außerhalb des von node.js angegebenen Wrappers
quelle
this
bezieht sich nicht mehr auf das globale Objektwindow.myVariable
welche überall funktionieren wird.=>
sondern verwenden stattdessen->
Coffeescript, um die Funktion unter dem Namespace this / global zu erstellenIvo hat es geschafft, aber ich werde erwähnen, dass es einen schmutzigen Trick gibt, den Sie verwenden können, obwohl ich ihn nicht empfehle, wenn Sie Stilpunkte anstreben: Sie können JavaScript-Code direkt in Ihr CoffeeScript einbetten, indem Sie ihn mit Backticks maskieren.
Dies ist jedoch der Grund, warum dies normalerweise eine schlechte Idee ist: Der CoffeeScript-Compiler kennt diese Variablen nicht, was bedeutet, dass sie nicht den normalen CoffeeScript-Gültigkeitsregeln entsprechen. Damit,
kompiliert zu
und jetzt hast du zwei
foo
s in verschiedenen bereichen. Es gibt keine Möglichkeit, den globalenfoo
Code von CoffeeScript zu ändern, ohne auf das globale Objekt zu verweisen, wie Ivy beschrieben hat.Dies ist natürlich nur dann ein Problem, wenn Sie
foo
in CoffeeScript eine Zuweisung vornehmen. Wennfoo
der Anfangswert (dh eine globale Konstante) schreibgeschützt ist, ist der Ansatz der eingebetteten JavaScript-Lösung möglicherweise irgendwie akzeptabel (wenn auch immer noch) nicht empfohlen).quelle
foo
Variable, weil sievar
hochgezogen wird (JS sucht nach allenvar
Deklarationen und interpretiert sie so, als ob sie oben auf der Funktion wären)expect = require('chai').expect;
machtexpect
Variablen in allen meinen Testdateien verfügbar!Sie können die Option -b übergeben, wenn Sie Code über ein Kaffeeskript unter node.js kompilieren. Der kompilierte Code ist der gleiche wie auf coffeescript.org.
quelle
-b
/--bare
geht direkt nach demcoffee
Befehl.Zur Antwort von Ivo Wetzel hinzufügen
Es scheint eine Kurzsyntax dafür zu geben
exports ? this
, die ich nur in einem Google-Gruppenbeitrag dokumentiert / erwähnt finden kann .Dh auf einer Webseite, um eine Funktion global verfügbar zu machen, deklarieren Sie die Funktion erneut mit einem
@
Präfix:quelle
Ich denke, was Sie erreichen wollen, kann einfach so gemacht werden:
Verwenden Sie beim Kompilieren des Kaffeeskripts den Parameter "-b".
-b
/--bare
Kompilieren Sie das JavaScript ohne den Funktionssicherheits-Wrapper der obersten Ebene.Also so etwas wie das:
coffee -b --compile somefile.coffee whatever.js
Dadurch wird Ihr Code genau wie auf der Website CoffeeScript.org ausgegeben.
quelle
Wenn Sie ein schlechter Mensch sind (ich bin ein schlechter Mensch), können Sie so einfach werden:
(->@)()
Wie in,
Dies funktioniert, da beim Aufrufen von a
Reference
zu einemFunction
'bare' (dhfunc()
anstelle vonnew func()
oderobj.func()
) etwas, das üblicherweise als 'Funktionsaufruf-Aufrufmuster' bezeichnet wird, immer anthis
das globale Objekt für diesen Ausführungskontext gebunden ist .Das obige CoffeeScript kompiliert einfach zu
(function(){ return this })()
; Wir üben dieses Verhalten aus, um zuverlässig auf das globale Objekt zuzugreifen.quelle
Da Coffeescript nur selten alleine verwendet wird, können Sie
global
Variablen verwenden, die entweder von node.js oder browserify (und von Nachkommen wie Coffeeify, Gulp Build-Skripten usw.) bereitgestellt werden.In node.js
global
befindet sich der globale Namespace.In browserify
global
ist gleichwindow
.Also nur:
quelle