如何在 CoffeeScript 中定义全局变量?
-
26-09-2019 - |
题
在 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.anything
和this
指的是全局对象。
所以...
@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';
现在你已经有了自己两个foo
s在不同的范围。有没有办法来修改全球从CoffeeScript的代码foo
而不引用全局对象,如常春藤说明。
当然,这只是一个问题,如果你在CoffeeScript中,如果foo
成为被赋予其初始值后只读(即它是一个全球性不变),则嵌入的JavaScript解决办法可能是有点儿进行分配,以foo
几分可接受(尽管仍然不推荐)。
您可以在您通过在node.js中咖啡脚本编译代码通过-b选项 编译后的代码将是相同的如上coffeescript.org。
我觉得你是想实现可以简单地这样做了什么:
当你正在编译的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
这个作品,因为调用Reference
到Function
“裸”(即,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