在 Coffeescript.org 上:

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

bawbag(5, 10) 

将编译为:

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

通过node.js下的coffee-script进行编译将其包装如下:

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

文件说:

如果您想创建用于使用其他脚本的顶级变量,请将其作为窗口上的属性或commonj中的导出对象上的属性附加。如果您同时定位CommonJ和浏览器,则存在的操作员(下面覆盖)为您提供了一种可靠的方法来弄清楚它们在哪里添加它们:根=出口?这

那么如何在 CoffeeScript 中定义全局变量。“将它们作为属性附加到窗口上”是什么意思?

有帮助吗?

解决方案

由于咖啡脚本没有 var 它会自动为咖啡脚本中的所有变量插入它,这样可以防止编译后的 JavaScript 版本将所有内容泄漏到 全局命名空间.

所以既然没有办法让一些东西“泄漏”到 全局命名空间 从咖啡脚本方面来看,您需要将全局变量定义为 全局对象.

将它们作为属性附加到窗口上

这意味着你需要做类似的事情 window.foo = 'baz';, ,它处理浏览器的情况,因为有 全局对象 是个 window.

Node.js

在 Node.js 中没有 window 对象,而是有 exports 传递到包装 Node.js 模块的包装器中的对象(请参阅: https://github.com/ry/node/blob/master/src/node.js#L321 ),所以在 Node.js 中你需要做的是 exports.foo = 'baz';.

现在让我们看一下您在文档中引用的内容:

...针对 CommonJS 和浏览器:根=出口?这

这显然是咖啡脚本,所以让我们看一下它实际编译成的内容:

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

首先它会检查是否 exports 已定义,因为尝试引用 JavaScript 中不存在的变量会产生语法错误(除非它与 typeof)

因此,如果 exports 存在,这就是 Node.js 中的情况(或者写得不好的 WebSite...) root 将指向 exports, ,否则到 this. 。有啥 this?

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

使用 .call 在函数上将绑定 this 在函数内部传递到第一个参数(如果是浏览器) this 现在将是 window 对象,对于 Node.js 来说,它将是 全球背景 这也可以作为 global 目的。

但既然你有 require Node.js 中的函数,无需为 global Node.js 中的对象,而是分配给 exports 然后由返回的对象 require 功能。

咖啡脚本

经过所有解释后,您需要执行以下操作:

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

这将声明我们的函数 foo 在全局命名空间中(无论发生什么)。
就这样 :)

其他提示

要我来说,似乎@atomicules具有最简单的答案,但我认为它可以更简单一点。你需要把你想成为全球任何之前@,所以它编译于this.anythingthis指的是全局对象。

所以...

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

bawbag(5, 10)

编译为...

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

和作品内和通过的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

伊沃钉它,但我会提到,有您可以使用一个使坏,但我不建议这样做,如果你打算为风格要点:你可以通过逃避在你的CoffeeScript直接嵌入JavaScript代码与反引号。

然而,这就是为什么这通常是一个坏主意:CoffeeScript的的编译器不知道这些变量的,这意味着他们将不服从正常的CoffeeScript作用域规则。所以,

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

编译成

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

现在你已经有了自己两个foos在不同的范围。有没有办法来修改全球从CoffeeScript的代码foo而不引用全局对象,如常春藤说明。

当然,这只是一个问题,如果你在CoffeeScript中,如果foo成为被赋予其初始值后只读(即它是一个全球性不变),则嵌入的JavaScript解决办法可能是有点儿进行分配,以foo几分可接受(尽管仍然不推荐)。

您可以在您通过在node.js中咖啡脚本编译代码通过-b选项 编译后的代码将是相同的如上coffeescript.org。

要添加到 伊沃·韦策尔的回答

似乎有一个简写语法 exports ? this 我只能找到记录/提到 谷歌群组发帖.

IE。在网页中要使函数全局可用,您可以使用 @ 字首:

<script type="text/coffeescript">
    @aglobalfunction = aglobalfunction = () ->
         alert "Hello!"
</script>

<a href="javascript:aglobalfunction()" >Click me!</a>

我觉得你是想实现可以简单地这样做了什么:

当你正在编译的CoffeeScript,使用 “-b” 参数。

-b / --bare 编译的JavaScript而不顶级功能安全的包装。

因此,像这样:coffee -b --compile somefile.coffee whatever.js

这将输出你的代码就像在CoffeeScript.org网站。

如果你是一个坏人(我是一个坏人。),就可以得到像这样简单:(->@)()

如,

(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer

这个作品,因为调用ReferenceFunction“裸”(即,func(),代替new func()obj.func())时,一些通常被称为的“函数调用调用模式”,总是结合this全局对象为执行上下文

在上面的CoffeeScript简单地编译为(function(){ return this })();因此我们行使这种行为能够可靠地访问全球对象。

由于CoffeeScript的很少上它自己的使用时,可以使用由任一的node.js供给global变量或browserify(等coffeeify,咽构建脚本等任何后代)。

在的node.js global是全局命名空间。

在browserify global等于window

所以,只要:

somefunc = ->
  global.variable = 123
scroll top