命名空间在 CoffeeScript 和 Rails 中如何工作?
-
24-12-2019 - |
题
我正在看这个咖啡脚本 代码 来自 Gitlab 并想知道它是如何工作的。
class Issue
constructor: ->
$('.edit-issue.inline-update input[type="submit"]').hide()
$(".issue-box .inline-update").on "change", "select", ->
$(this).submit()
$(".issue-box .inline-update").on "change", "#issue_assignee_id", ->
$(this).submit()
@Issue = Issue
似乎这仅在与问题相关的视图中使用,但在问题 html 中的任何位置都没有调用它。难道这背后有什么神奇的事情发生吗?还有什么意义 @Issue = Issue
线?
解决方案
@Issue = Issue
只是将局部变量发布到全局范围。这与 ruby 或 Rails 无关。这纯粹是一个咖啡脚本习惯用法。
CoffeeScript 在包装器内执行,该包装器旨在防止在全局范围内创建变量。在这个包装纸中, this
(或者 @
) 是全局对象。
所以这:
class Issue
constructor: ->
@Issue = Issue;
编译大约为这个JS:
(function() {
var Issue;
Issue = (function() {
function Issue() {}
return Issue;
})();
this.Issue = Issue;
}.call(window));
在那篇JS中, window
变成 this
, ,窗口的属性成为全局变量。所以从现在开始,你只需要输入 Issue
在任何其他 JS 文件中,您都会有问题构造函数。
如果没有 @Issue = Issue
线, 的 Issue
构造函数在该代码之外永远不可用,并且没有其他文件可以使用它。
换句话说,它与以下内容相同:
window.Issue = Issue;
实际上大多数时候我更喜欢这一点。更清楚发生了什么 window
总是意味着 window
, , 但 @
取决于它出现的位置,它可以意味着很多东西。
其他提示
就像在JavaScript中一样,CoffeeScript中没有正确的命名法。@Issue = Issue
转换为this.Issue = Issue
。我的猜测是,这种代码段是在构建过程中与其他文件连接,其中一个打开匿名关闭,类似于下面的封闭。
var namespace1 = {subnamespace1: {}};
(function() {
// Several concatenated files
}).call(namespace1.subnamespace1);
. 不隶属于 StackOverflow