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

2022-01-24 00:00:00 javascript coffeescript

在 Coffeescript.org 上:

On 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 编译会这样包装:

compiling via coffee-script under node.js wraps that so:

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

文档说:

如果您想创建顶级变量供其他脚本使用,将它们作为属性附加到窗口或导出对象中通用JS.存在运算符(如下所述)为您提供如果您同时针对两者,则可以确定将它们添加到何处的可靠方法CommonJS 和浏览器:root = 出口?这个

If you'd like to create top-level variables for other scripts to use, attach them as properties on window, or on the exports object in CommonJS. The existential operator (covered below), gives you a reliable way to figure out where to add them, if you're targeting both CommonJS and the browser: root = exports ? this

我如何在 CoffeeScript 中定义全局变量.'将它们作为属性附加到窗口'是什么意思?

How do I define Global Variables then in CoffeeScript. What does 'attach them as properties on window' mean?

推荐答案

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

Since coffee script has no var statement it automatically inserts it for all variables in the coffee-script, that way it prevents the compiled JavaScript version from leaking everything into the global namespace.

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

So since there's no way to make something "leak" into the global namespace from the coffee-script side of things on purpose, you need to define your global variables as properties of the global object.

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

attach them as properties on window

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

This means you need to do something like window.foo = 'baz';, which handles the browser case, since there the global object is the window.

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

In Node.js there's no window object, instead there's the exports object that gets passed into the wrapper that wraps the Node.js module (See: https://github.com/ry/node/blob/master/src/node.js#L321 ), so in Node.js what you would need to do is exports.foo = 'baz';.

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

Now let us take a look at what it states in your quote from the docs:

...同时针对 CommonJS 和浏览器: root = exports ?这个

...targeting both CommonJS and the browser: root = exports ? this

这显然是coffee-script,所以让我们看看它实际编译成什么:

This is obviously coffee-script, so let's take a look into what this actually compiles to:

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

首先它会检查是否定义了 exports,因为试图在 JavaScript 中引用一个不存在的变量会产生一个 SyntaxError(除非它与 typeof 一起使用)

First it will check whether exports is defined, since trying to reference a non existent variable in JavaScript would otherwise yield an SyntaxError (except when it's used with typeof)

所以如果 exports 存在,在 Node.js 中就是这种情况(或者在一个写得不好的网站......)根将指向 exports,否则指向 <代码>这个.那么这个是什么?

So if exports exists, which is the case in Node.js (or in a badly written WebSite...) root will point to exports, otherwise to this. So what's this?

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

在函数上使用 .call 会将函数内部的 this 绑定到传递的第一个参数,如果浏览器 this 会现在是 window 对象,如果是 Node.js,它将是 global context,它也可用作 global 对象.

Using .call on a function will bind the this inside the function to the first parameter passed, in case of the browser this would now be the window object, in case of Node.js it would be the global context which is also available as the global object.

但是由于您在 Node.js 中有 require 函数,因此无需为 Node.js 中的 global 对象分配某些内容,而是分配给 exports 对象,然后由 require 函数返回.

But since you have the require function in Node.js, there's no need to assign something to the global object in Node.js, instead you assign to the exports object which then gets returned by the require function.

在所有这些解释之后,这就是你需要做的:

After all that explanation, here's what you need to do:

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

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

This will declare our function foo in the global namespace (whatever that happens to be).
That's all :)

相关文章