2

每个 dart 文件的已编译 javascript 的顶部都是这个奇怪的列表。

function dart() {
  this.x = 0;
  delete this.x;
}
var A = new dart;
var B = new dart;
var C = new dart;
var D = new dart;
var E = new dart;
var F = new dart;
... etc etc ...
var Z = new dart;

我扫描了代码的其余部分以寻找 .A (或任何其他字母),但没有运气。这究竟是为了什么目的?最终结果是 dart() 函数/构造函数的 AZ 实例是空类对象,但有什么用呢?

使用像/[A-Z]{1}\./我这样的正则表达式发现一些字母实例用属性装饰,然后所有 27 个字母都通过这个函数运行:

function convertToFastObject(properties) {
  function MyClass() {
  }
  MyClass.prototype = properties;
  new MyClass();
  return properties;
}
;
A = convertToFastObject(A);
B = convertToFastObject(B);
C = convertToFastObject(C);
... etc etc ...
Z = convertToFastObject(Z);

这让我更加困惑。因为那行似乎SomeObject = convertToFastObject(SomeObject);没有变化。

编辑/更新:找到了对 convertToFastObject 及其前身 dart() 类的解释 -为什么 convertToFastObject 函数让它变得更快?这是一个优化技巧。仍然给我留下一个问题,为什么 AZ 实例列表,它只是另一个优化技巧还是某种代码哈希表?

4

2 回答 2

5

The A-Z classes are reserved globals for various Dart libraries. A small number of these are used for specific libraries, as you can see in the source:

static const reservedGlobalObjectNames = const <String>[
    "A",
    "B",
    "C", // Global object for *C*onstants.
    "D",
    "E",
    "F",
    "G",
    "H", // Global object for internal (*H*elper) libraries.
    // I is used for used for the Isolate function.
    "J", // Global object for the interceptor library.
    "K",
    "L",
    "M",
    "N",
    "O",
    "P", // Global object for other *P*latform libraries.
    "Q",
    "R",
    "S",
    "T",
    "U",
    "V",
    "W", // Global object for *W*eb libraries (dart:html).
    "X",
    "Y",
    "Z",
];

All the rest seem to be be used for isolates as is indicated by the globalObjectFor method, and viewing the results of dart2js compiled code that uses isolates.

于 2014-12-24T03:59:46.530 回答
3

这些对象包含已在 Dart 程序中定义的所有静态变量(全局变量、类...)(并且尚未被树摇动)。我们称它们为“全局对象”。

这里有一些历史:最初我们只有一个全局对象,它位于 JS 的顶层。我们不想(并且仍然不想)污染 JavaScript 的全局命名空间并将自己限制在一个对象上。我们不只是将程序包装到一个匿名函数中,因为这会减慢程序的速度。

事情发展了...... JavaScript 引擎在嵌套范围内变得更快,我们将代码移动到匿名函数中。这使得切换到更多“顶级”(包装在函数中)对象成为可能。我们还发现 JS 引擎对包含太多属性的对象非常不利。因此,我们将一个全局对象切割成更小的部分,并将编译后的静态/类分布到不同的全局对象中。Dart 类的最终位置基于内部库的预定义映射,以及其他库的库名称。

我们不只是运行到某个数字(比如“A”为 1000,“B”为 1000,...),因为这意味着 JS 输出在进行微小更改时可能会发生显着变化。

我们现在可以摆脱这些对象,但我们还没有看到对它的需求。JS 引擎非常擅长优化对象访问。我还没有测试过,但我认为使用同一个对象的两个函数可能更快或与使用两个局部变量一样快。

于 2014-12-24T11:44:54.977 回答