317 votes

CoffeeScript et variables globales

Sur Coffeescript.org:

bawbag = (x, y) ->
    z = (x * y)

bawbag(5, 10) 

dresser:

var bawbag;
bawbag = function(x, y) {
  var z;
  return (z = (x * y));
};
bawbag(5, 10);

la compilation via coffee-script sous node.js enveloppe la sorte:

(function() {
  var bawbag;
  bawbag = function(x, y) {
    var z;
    return (z = (x * y));
  };
  bawbag(5, 10);
}).call(this);

Docs disent:

Si vous souhaitez créer des variables globales pour d'autres scripts à utiliser, joindre en tant que propriétés de la fenêtre, ou sur les exportations de l'objet dans CommonJS. Les existentielle de l'opérateur (ci-dessous), vous donne un moyen fiable de déterminer où les ajouter, si vous ciblez les deux CommonJS et le navigateur: root = exportations ? cette

Comment puis-je définir des Variables Globales puis en CoffeeScript. Qu'est-ce que les joindre en tant que propriétés dans la fenêtre"?

419voto

Ivo Wetzel Points 27802

Depuis le café le script n'a pas d' var déclaration qu'il insère automatiquement pour toutes les variables dans le coffee-script, de cette façon, il empêche la compilation version JavaScript de fuite tout en l' espace de noms global.

Donc, puisqu'il n'y a pas moyen de faire quelque chose de "fuite" dans l' espace de noms global du coffee-script côté des choses sur le but, vous devez définir vos variables globales comme des propriétés de l' objet global.

joindre en tant que propriétés de la fenêtre

Cela signifie que vous devez faire quelque chose comme window.foo = 'baz';, qui gère le navigateur de l'affaire, car il y a l' objet global est l' window.

Node.js

Dans Node.js il n'y a pas d' window objet, au lieu de cela, il y a la exports objet qui est passée dans le wrapper qui enveloppe le Node.js module (Voir: https://github.com/ry/node/blob/master/src/node.js#L321 ), donc dans Node.js ce que vous devez faire est de exports.foo = 'baz';.

Maintenant, laissez-nous jeter un oeil à ce qu'il dit dans votre citation de la documentation:

...visant à la fois CommonJS et le navigateur: root = exportations ? cette

C'est évidemment le café-script, donc, nous allons jeter un regard sur ce que tout cela compile:

var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;

D'abord, il va vérifier si exports est défini, puisqu'en essayant de faire référence à un inexistante variable en JavaScript serait autrement le rendement d'une SyntaxError (sauf lorsqu'il est utilisé avec des typeof)

Donc, si exports , ce qui est le cas dans Node.js (ou dans un mal écrite, Site web...) racine de point de exports, sinon à l' this. Alors, quel est this?

(function() {...}).call(this);

À l'aide de .call sur une fonction de lier l' this à l'intérieur de la fonction pour le premier paramètre transmis, dans le cas du navigateur this sera désormais l' window objet, en cas de Node.js il serait le contexte global qui est également disponible en tant que global objet.

Mais puisque vous avez l' require fonction dans Node.js, il n'y a pas besoin d'assigner quelque chose à l' global objet Node.js au lieu de vous attribuer à l' exports objet qui est ensuite renvoyé par l' require fonction.

Coffee-Script

Après toutes ces explications, voici ce que vous devez faire:

root = exports ? this
root.foo = -> 'Hello World'

Cela va déclarer notre fonction foo en l'espace de noms global (quel qu'il puisse être).
C'est tout :)

57voto

Billy Moon Points 21439

Pour moi, il semble que @atomicules a la réponse la plus simple, mais je pense que cela peut être simplifié un peu plus. Vous devez placer un @ avant tout ce que vous voulez être global, de sorte qu'il compile à this.anything et this à l'objet global.

alors...

 @bawbag = (x, y) ->
    z = (x * y)

bawbag(5, 10)
 

compile à ...

 this.bawbag = function(x, y) {
  var z;
  return z = x * y;
};
bawbag(5, 10);
 

et fonctionne à l'intérieur et à l'extérieur du wrapper donné par node.js

 (function() {
    this.bawbag = function(x, y) {
      var z;
      return z = x * y;
    };
    console.log(bawbag(5,13)) // works here
}).call(this);

console.log(bawbag(5,11)) // works here
 

33voto

Trevor Burnham Points 43199

Ivo cloué, mais je vais mentionner qu'il est un sale truc que vous pouvez utiliser, mais je ne le recommande pas si vous allez pour les points de style: Vous pouvez intégrer du code JavaScript directement dans votre CoffeeScript en s'échappant avec backticks.

Cependant, voici pourquoi c'est généralement une mauvaise idée: La CoffeeScript compilateur est pas au courant de ces variables, ce qui signifie qu'ils ne vont pas obéir à la normale CoffeeScript règles de portée. Donc,

`foo = 'bar'`
foo = 'something else'

compile de

foo = 'bar';
var foo = 'something else';

et maintenant, vous avez vous-même deux foos dans des champs d'application différents. Il n'y a aucun moyen de modifier le global foo de CoffeeScript code sans faire référence à l'objet global, que le Lierre décrit.

Bien sûr, c'est seulement un problème si vous faites une cession à l' foo en CoffeeScript-si foo est devenu en lecture seule après avoir donné sa valeur initiale (c'est à dire que c'est une constante globale), puis le JavaScript intégré approche de la solution pourrait être un peu sorta acceptable (mais toujours pas recommandé).

11voto

phongnh Points 81

Vous pouvez passer l'option -b lorsque vous compilez du code via un script-café sous node.js. Le code compilé sera le même que sur coffeescript.org.

9voto

Sankalp Singha Points 1154

Je pense que ce que vous essayez de réaliser peut simplement être fait comme ceci:

Pendant que vous compilez le café, utilisez le paramètre "-b".

-b / --bare Compile le JavaScript sans l'encapsuleur de sécurité 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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X