Sur Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
compilerait pour:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
la compilation via coffee-script sous node.js enveloppe ainsi:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Les documents disent:
Si vous souhaitez créer des variables de niveau supérieur pour d'autres scripts à utiliser, attachez-les en tant que propriétés sur la fenêtre ou sur l'objet exports dans CommonJS. L'opérateur existentiel (décrit ci-dessous) vous donne un moyen fiable de savoir où les ajouter, si vous ciblez à la fois CommonJS et le navigateur: root = exports? ce
Comment puis-je définir des variables globales dans CoffeeScript. Que signifie «les attacher en tant que propriétés sur la fenêtre»?
javascript
coffeescript
Handloomweaver
la source
la source
window
objet ou l'exports
objet. pas besoin de créer de variables globales.window
(ouglobal
sur nodejs)Réponses:
Étant donné que le script coffee n'a pas de
var
déclaration, il l'insère automatiquement pour toutes les variables dans le script coffee, de cette façon, il empêche la version JavaScript compilée de tout divulguer dans l' espace de noms global .Donc, puisqu'il n'y a aucun moyen de faire quelque chose "fuir" dans l' espace de noms global du côté café-script des choses, vous devez définir vos variables globales en tant que propriétés de l' objet global .
Cela signifie que vous devez faire quelque chose comme
window.foo = 'baz';
, qui gère le cas du navigateur, car l' objet global est lewindow
.Node.js
Dans Node.js, il n'y a pas d'
window
objet, mais plutôt l'exports
objet qui est passé dans le wrapper qui enveloppe le module Node.js (Voir: https://github.com/ry/node/blob/master/src/node.js# L321 ), donc dans Node.js ce que vous devez faire estexports.foo = 'baz';
.Voyons maintenant ce qu'il indique dans votre citation de la documentation:
Ceci est évidemment un script de café, alors regardons ce que cela compile réellement:
Tout d'abord, il vérifiera si
exports
est défini, car essayer de référencer une variable inexistante en JavaScript produirait sinon une SyntaxError (sauf lorsqu'elle est utilisée avectypeof
)Donc, s'il
exports
existe, ce qui est le cas dans Node.js (ou dans un site Web mal écrit ...), la racine pointeraexports
, sinonthis
. Alors quoithis
?L'utilisation
.call
d'une fonction liera l'this
intérieur de la fonction au premier paramètre passé, dans le cas où le navigateurthis
serait maintenant l'window
objet, dans le cas de Node.js, ce serait le contexte global qui est également disponible en tantglobal
qu'objet.Mais puisque vous avez la
require
fonction dans Node.js, il n'est pas nécessaire d'affecter quelque chose à l'global
objet dans Node.js, à la place vous attribuez à l'exports
objet qui est ensuite renvoyé par larequire
fonction.Café-Script
Après toutes ces explications, voici ce que vous devez faire:
Cela déclarera notre fonction
foo
dans l'espace de noms global (quel qu'il soit).C'est tout :)
la source
global
,GLOBAL
et lesroot
objets Node.js?ReferenceError
?(exports ? this).foo = -> 'Hello World'
global = exports ? this
. L'affirmation selon laquelle "dans le cas de Node.js ce serait le contexte global ..." est erronée car lathis
variable, lorsqu'elle est requise ou exécutée par node.js, est évaluée comme la portée du module. Donc, si vous vous attendez à ce que les accessoires le rendent accessible à l'échelle mondiale, vous serez déçu. Si vous souhaitez définir les choses globalement dans le contexte node.js, vous devez utiliser laglobal
variable plutôt quethis
.Il me semble que @atomicules a la réponse la plus simple, mais je pense qu'elle peut être simplifiée un peu plus. Vous devez mettre un
@
avant tout ce que vous voulez être global, afin qu'il se compilethis.anything
et fassethis
référence à l'objet global.alors...
compile pour ...
et fonctionne à l'intérieur et à l'extérieur du wrapper donné par node.js
la source
this
qu'alors ne fait plus référence à l'objet globalwindow.myVariable
qui fonctionnera n'importe où.=>
place de->
celle qui indique à coffeescript de créer la fonction sous l'espace de noms this / globalIvo l'a cloué, mais je mentionnerai qu'il y a une sale astuce que vous pouvez utiliser, bien que je ne le recommande pas si vous recherchez des points de style: vous pouvez incorporer du code JavaScript directement dans votre CoffeeScript en l'échappant avec des astuces.
Cependant, voici pourquoi il s'agit généralement d'une mauvaise idée: le compilateur CoffeeScript ne connaît pas ces variables, ce qui signifie qu'elles n'obéiront pas aux règles de cadrage CoffeeScript normales. Alors,
compile en
et maintenant vous avez deux
foo
s dans des portées différentes. Il n'y a aucun moyen de modifier le global àfoo
partir du code CoffeeScript sans référencer l'objet global, comme Ivy l'a décrit.Bien sûr, cela n'est un problème que si vous effectuez une affectation
foo
dans CoffeeScript - si vousfoo
devenez en lecture seule après avoir reçu sa valeur initiale (c'est-à-dire qu'il s'agit d'une constante globale), alors l'approche de la solution JavaScript intégrée peut être un peu acceptable (bien que toujours non recommandé).la source
foo
variable locale , en raison duvar
levage (JS recherche toutes lesvar
déclarations et les interprète comme si elles étaient au sommet de la fonction)expect = require('chai').expect;
rend laexpect
variable disponible dans tous mes fichiers de test!Vous pouvez passer l'option -b lorsque vous compilez du code via coffee-script sous node.js. Le code compilé sera le même que sur coffeescript.org.
la source
-b
/--bare
va directement après lecoffee
commande.Pour ajouter à la réponse d'Ivo Wetzel
Il semble y avoir une syntaxe abrégée pour
exports ? this
laquelle je ne peux trouver que documenté / mentionné sur une publication de groupe Google .C'est-à-dire que dans une page Web pour rendre une fonction disponible globalement, vous déclarez à nouveau la fonction avec un
@
préfixe:la source
Je pense que ce que vous essayez de réaliser peut simplement être fait comme ceci:
Pendant que vous compilez le coffeescript, utilisez le paramètre "-b".
-b
/--bare
Compilez le JavaScript sans le wrapper de sécurité de fonction de niveau supérieur.Donc quelque chose comme ça:
coffee -b --compile somefile.coffee whatever.js
Cela affichera votre code comme sur le site CoffeeScript.org.
la source
Si vous êtes une mauvaise personne (je suis une mauvaise personne), vous pouvez être aussi simple que cela:
(->@)()
Un péché,
Cela fonctionne, car lorsque vous invoquez un
Reference
vers unFunction
'nu' (c'est-à-direfunc()
, au lieu denew func()
ouobj.func()
), quelque chose communément appelé le 'modèle d'invocation d'appel de fonction', se lie toujoursthis
à l'objet global pour ce contexte d'exécution .Le CoffeeScript ci-dessus se compile simplement en
(function(){ return this })()
; nous exerçons donc ce comportement pour accéder de manière fiable à l'objet global.la source
Comme coffeescript est rarement utilisé seul, vous pouvez utiliser une
global
variable fournie par node.js ou browserify (et tout descendant comme coffeeify, gulp build scripts, etc.).Dans node.js
global
est l'espace de noms global.Dans browserify
global
est égal àwindow
.Donc, juste:
la source