在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);
文件说:
如果要为其他要使用的脚本创建顶级变量,请将它们作为属性附加到窗口或CommonJS中的exports对象上 . 存在运算符(如下所述)为您提供了一种可靠的方法来确定添加它们的位置,如果您的目标是CommonJS和浏览器:root = exports?这个
如何在CoffeeScript中定义全局变量 . “将它们作为窗口上的属性附加”是什么意思?
8 回答
由于咖啡脚本没有
var
语句,它会自动为咖啡脚本中的所有变量插入它,这样就可以防止编译好的JavaScript版本泄漏到 global namespace 中 .因此,由于无法有目的地从咖啡脚本方面向 global namespace 创建"leak",因此需要将全局变量定义为 global object 的属性 .
这意味着您需要执行
window.foo = 'baz';
之类的操作,它处理浏览器的情况,因为 global object 是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';
.现在让我们看一下文档引用中的内容:
这显然是咖啡脚本,所以让我们来看看它实际编译的内容:
首先,它将检查
exports
是否已定义,因为尝试在JavaScript中引用不存在的变量否则会产生SyntaxError(除非它与typeof
一起使用)因此,如果
exports
存在,Node.js中的情况(或编写错误的WebSite ...)根将指向exports
,否则指向this
. 那是什么this
?在函数上使用
.call
会将函数内部的this
绑定到传递的第一个参数,如果浏览器this
现在是window
对象,则在Node.js的情况下,它将是 global context ,它也可用作global
对象 .但是由于你在Node.js中有
require
函数,所以不需要为Node.js中的global
对象赋值,而是分配给exports
对象,然后由require
函数返回 .咖啡脚本
完成所有解释之后,这就是您需要做的事情:
这将在全局命名空间中声明我们的函数
foo
(无论发生什么) .就这样 :)
对我来说,似乎@atomicules有最简单的答案,但我认为它可以简化一点 . 你需要在你希望成为全局的任何东西之前放置
@
,以便它编译为this.anything
并且this
指向全局对象 .所以......
编译成......
并在node.js给出的包装器内部和外部工作
Ivo钉了它,但我会提到你可以使用一个肮脏的技巧,但是如果你想要使用样式点我不推荐它:你可以通过使用反引号转义它来直接在你的CoffeeScript中嵌入JavaScript代码 .
但是,这就是为什么这通常是一个坏主意:CoffeeScript编译器不知道这些变量,这意味着它们不会遵守常规的CoffeeScript范围规则 . 所以,
编译成
现在你已经有了两个不同范围的
foo
. 正如Ivy所描述的那样,没有引用全局对象就无法修改CoffeeScript代码中的全局foo
.当然,如果你在CoffeeScript中对
foo
进行赋值,这只是一个问题 - 如果foo
在给定其初始值后变为只读(即它是一个全局常量),那么嵌入式JavaScript解决方案方法可能有点可接受(虽然仍然不推荐) .在node.js下通过coffee-script编译代码时,可以传递-b选项 . 编译后的代码与coffeescript.org上的代码相同 .
要添加到Ivo Wetzel's answer
似乎有
exports ? this
的简写语法,我只能在Google group posting上找到记录/提及的语法 .即在网页中创建一个功能在全局可用时,您使用
@
前缀再次声明该函数:我认为你想要实现的目标可以简单地完成:
在编译coffeescript时,请使用“-b”参数 .
-b
/--bare
在没有顶级功能安全包装的情况下编译JavaScript .所以像这样:
coffee -b --compile somefile.coffee whatever.js
这将输出您的代码,就像在CoffeeScript.org网站中一样 .
如果你是一个坏人 . ),你可以这样简单:
(->@)()
如,
这是有效的,因为当调用
Reference
到Function
'裸'(即func()
,而不是new func()
或obj.func()
)时,通常称为'函数调用调用模式',总是将this
绑定到全局对象 . execution context .上面的CoffeeScript只编译为
(function(){ return this })()
;所以我们正在行使这种行为来可靠地访问全局对象 .由于coffeescript很少单独使用,你可以使用node.js或browserify提供的
global
变量(以及任何后代,如coffeeify,gulp构建脚本等) .在node.js中,
global
是全局命名空间 .在browserify中
global
等于window
.所以就: