Harmen 的回答非常好,但让我详细说明一下 CoffeeScript 编译器在何处完成此操作以及原因。
当你编译一些东西时coffee -c foo.coffee
,你总会得到一个foo.js
看起来像这样:
(function() {
...
}).call(this);
这是为什么?好吧,假设你做了一个像这样的作业
x = 'stringy string'
in foo.coffee
。当它看到这个时,编译器会问:x
已经存在于此范围内,还是外部范围内?如果没有,它会放置一个var x
JavaScript 输出中该范围顶部的声明。
现在假设你写
x = 42
in bar.coffee
,编译两者,然后连接foo.js
with bar.js
用于部署。你会得到
(function() {
var x;
x = 'stringy string';
...
}).call(this);
(function() {
var x;
x = 42;
...
}).call(this);
So the x
in foo.coffee
和x
in bar.coffee
彼此完全隔离。这是 CoffeeScript 的重要组成部分:变量永远不会从一个 .coffee 文件泄漏到另一个 .coffee 文件,除非显式导出(通过附加到共享全局,或exports
在 Node.js 中)。
您可以使用以下方法覆盖它-b
(“裸露”)标记为coffee
,但这应该只在非常特殊的情况下使用。如果您在上面的示例中使用它,您将得到的输出将是
var x;
x = 'stringy string';
...
var x;
x = 42;
...
这可能会产生可怕的后果。要自己测试一下,请尝试添加setTimeout (-> alert x), 1
in foo.coffee
。请注意,如果您使用两个单独的 JS 文件,则不必自己连接两个 JS 文件<script>
标签将它们包含在页面上,它们仍然有效地作为一个文件运行。
通过隔离不同模块的作用域,CoffeeScript 编译器使您免于担心项目中的不同文件是否可能使用相同的局部变量名称。这是 JavaScript 世界中的常见做法(例如,参见jQuery 源代码,或任何 jQuery 插件)——CoffeeScript 会为您处理好这一切。