如何在 CoffeeScript 中定义全局变量?

2022-08-29 23:56:29

在 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包装如下:

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

文档说:

如果要创建顶级变量供其他脚本使用,请将它们作为属性附加到窗口上,或附加到 CommonJS 中的导出对象上。存在运算符(如下所述)为您提供了一种可靠的方法来找出添加它们的位置,如果您同时面向CommonJS和浏览器:root = 导出?这

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


答案 1

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

因此,由于没有办法故意使某些东西从咖啡脚本方面“泄漏”到全局命名空间中,因此您需要将全局变量定义为全局对象的属性。

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

这意味着您需要执行类似 ,它处理浏览器情况,因为那里的全局对象是 .window.foo = 'baz';window

节点.js

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

现在让我们来看看它在文档中引用的内容:

...同时针对 CommonJS 和浏览器:root = 导出 ?这

这显然是咖啡脚本,所以让我们来看看它实际上编译成什么:

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

首先,它将检查是否定义了,因为尝试在JavaScript中引用不存在的变量将产生SynathaneError(除非它与exportstypeof)

因此,如果存在,在 Node 中就是这种情况.js(或在写得不好的网站...)根将指向 ,否则指向 。那是什么?exportsexportsthisthis

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

在函数上使用会将函数内部绑定到传递的第一个参数,如果浏览器现在是对象,如果是Node.js它将是全局上下文,也可以用作对象。.callthisthiswindowglobal

但是,由于您在 Node.js 中具有函数,因此无需在 Node.js 中为对象分配某些内容,而是将其分配给该对象,然后由函数返回。requireglobalexportsrequire

咖啡脚本

在所有这些解释之后,您需要执行以下操作:

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

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


答案 2

对我来说,@atomicules有最简单的答案,但我认为可以再简化一点。您需要将 a 放在任何要成为全局对象的内容之前,以便它编译并引用全局对象。@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);

并在节点给出的包装器内外工作.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