【问题标题】:How is package scope achieved?包范围是如何实现的?
【发布时间】:2013-12-27 06:24:05
【问题描述】:

流星文档(参见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 对象中。绝对不是我想要的。还有流星?他们以某种方式管理它。他们一定使用了一些我不懂的魔法。

【问题讨论】:

  • 关于您的 iffy 以及为什么它没有按预期工作:未使用 var 声明的每个变量都被自动假定为全局对象的属性。
  • @nietonfir 当然,这就是 Meteor 解析 JavaScript 以插入包范围变量的预声明的原因;见 Akshat 的回答。

标签: scope meteor


【解决方案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

因此提取了全局变量,并使用全局变量、导入和导出重新构建了文件,这就是它自己命名空间的方式。

【讨论】:

  • 我也想通了,但是我没有找到像linker.js 这样的细节。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2020-09-15
  • 2021-10-31
  • 2010-12-09
  • 2015-09-19
相关资源
最近更新 更多