CoffeeScript模块的模式 [英] Pattern for CoffeeScript modules

查看:104
本文介绍了CoffeeScript模块的模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在查看 Github上的CoffeeScript的源代码时,我注意到大多数模块(如果不是全部)定义如下:

 (function(){
...
})。 );

此模式看起来像是将整个模块包装在匿名函数中并调用自身。



这种方法的优点(和缺点)是什么?有没有其他方法来实现相同的目标?

解决方案

Harmen的答案是相当不错的,但让我阐述一下CoffeeScript编译器在这里做什么以及为什么。 / p>

当你使用 coffee -c foo.coffee 编译一些东西时,你总会得到一个 foo.js ,如下所示:

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

为什么?嗯,假设你把像

这样的赋值

  x ='stringy string'

foo.coffee 中。当它看到,编译器询问: x 已经存在于这个范围,或外部范围?如果没有,它会在JavaScript输出的范围顶部放置一个 var x 声明。



现在假设

  x = 42 

bar.coffee 中,编译两者,并将 foo.js 与< c $ c> bar.js 进行部署。你会得到

 (function(){
var x;
x ='stringy string';
...
})。call(this);
(function(){
var x;
x = 42;
...
})。

因此 x c> foo.coffee ,并且 bar.coffee 中的 x 另一个。这是CoffeeScript的重要部分:变量从不会从一个.coffee文件泄漏到另一个除非显式导出(通过附加到共享全局或 exports in Node.js)。



您可以使用 -b )标志为 coffee ,但这只应在非常特殊的情况下使用。如果你使用上面的例子,你会得到的输出是

  var x; 
x ='stringy string';
...
var x;
x = 42;
...

这可能会有可怕的后果。要自行测试,请尝试在 foo.coffee 中添加 setTimeout( - > alert x),1 。注意,你不必自己连接两个JS文件 - 如果你使用两个单独的< script> 标签将它们包括在页面上,它们仍然有效地运行作为一个文件。



通过隔离不同模块的范围,CoffeeScript编译器可以避免您担心项目中不同的文件是否可能使用相同的局部变量名。这是JavaScript世界中的常见做法(例如,参见 jQuery源),或者任何jQuery插件)-CoffeeScript只是为你照顾。


While reviewing the source code for CoffeeScript on Github, I noticed that most, if not all, of the modules are defined as follows:

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

This pattern looks like it wraps the entire module in an anonymous function and calls itself.

What are the pros (and cons) of this approach? Are there other ways to accomplish the same goals?

解决方案

Harmen's answer is quite good, but let me elaborate a bit on where this is done by the CoffeeScript compiler and why.

When you compile something with coffee -c foo.coffee, you will always get a foo.js that looks like this:

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

Why is that? Well, suppose you put an assignment like

x = 'stringy string'

in foo.coffee. When it sees that, the compiler asks: Does x already exist in this scope, or an outer scope? If not, it puts a var x declaration at the top of that scope in the JavaScript output.

Now suppose you write

x = 42

in bar.coffee, compile both, and concatenate foo.js with bar.js for deployment. You'll get

(function() {
  var x;
  x = 'stringy string';
  ...
}).call(this);
(function() {
  var x;
  x = 42;
  ...
}).call(this);

So the x in foo.coffee and the x in bar.coffee are totally isolated from one another. This is an important part of CoffeeScript: Variables never leak from one .coffee file to another unless explicitly exported (by being attached to a shared global, or to exports in Node.js).

You can override this by using the -b ("bare") flag to coffee, but this should only be used in very special cases. If you used it with the above example, the output you'd get would be

var x;
x = 'stringy string';
...
var x;
x = 42;
...

This could have dire consequences. To test this yourself, try adding setTimeout (-> alert x), 1 in foo.coffee. And note that you don't have to concatenate the two JS files yourself—if you use two separate <script> tags to include them on a page, they still effectively run as one file.

By isolating the scopes of different modules, the CoffeeScript compiler saves you from the headache of worrying whether different files in your project might use the same local variable names. This is common practice in the JavaScript world (see, for instance, the jQuery source, or just about any jQuery plugin)—CoffeeScript just takes care of it for you.

这篇关于CoffeeScript模块的模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆