包装范围如何实现?

时间:2013-12-26 21:40:31

标签: scope meteor

Meteor文档(请参阅Namespacing部分)说:

  

当您声明顶级变量时,您可以选择。您可以创建变量File Scope或Package Scope。

// File Scope. This variable will be visible only inside this
// one file. Other files in this app or package won't see it.
var alicePerson = {name: "alice"};

// Package Scope. This variable is visible to every file inside
// of this package or app. The difference is that 'var' is
// omitted.
bobPerson = {name: "bob"};

这真的很好。如果一个包有多个源代码文件,那么这些文件可以共享变量,但可以保留世界其他地方。但是我开始怀疑。

他们到底如何实现包装范围?

起初我以为他们是通过立即调用的函数表达式实现的。你知道像这样的结构:

(function() { /* your code here */ })();

所以我试图在控制台中模拟这种行为。我定义了一个这样的变量:x = "Package scope candidate";

我进入了控制台:

(function() {
    x = "Package scope candidate";
})();
console.log(x);

我在控制台中获得了"Package scope candidate"。多么令人失望。变量x落在全球范围内。在Window对象中。绝对不是我想要的。和流星?他们以某种方式管理它。他们必须使用一些我不理解的魔法。

1 个答案:

答案 0 :(得分:1)

看起来他们重新定义了文件顶部的变量。

例如:

x = "Package scope candidate"

会变成

(function() {
    var x;
    (function() {
        x = "Package scope candidate";
    }).call(this);
}).call(this);

有一个解释器可以查找变量并将它们添加到顶部,以便它们成为范围到文件的范围,从而反映了包的范围。

如果你看一下https://github.com/meteor/meteor/blob/devel/tools/linker.js,你可以找到一个名为jsAnalyze的东西,它围绕文件查找全局变量以在文件顶部进行重新扫描。 在将文件提供给客户端之前,它将以上述方式重新打包。

jsAnalyze包会查看https://github.com/meteor/meteor/blob/94c7833c82ac6ab62c36b4a39ee315199233aef9/packages/js-analyze/js_analyze.js

所以提取全局变量&该文件使用全局变量,导入和导出重新构建,这就是它自己的命名空间。