For dartjs what is the odd list of alphabet ( A to Z ) empty class instances for?

Issue

At the top of every dart file’s compiled javascript is this odd list.

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;

I scanned through the rest of the code looking for .A ( or any of the other letters ) without luck. What purpose does this serve exactly? The end result is that the A-Z instances of the dart() function/constructor are empty class objects, but to what use?

Using a regex like /[A-Z]{1}\./ I did find a few of the letter instances are decorated with properties and then all 27 letters are run through this function:

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);

Which has further confused the hell out of me. As that line seems to read like SomeObject = convertToFastObject(SomeObject); without change.

Edit/Update:
Found an explanation for the convertToFastObject and it’s predecessor dart() class – Why the convertToFastObject function make it fast? It’s an optimization trick. Still leaves me with the question of why the A-Z list of instances, is it just another optimization trick or some sort of hash table of code?

Solution

These objects contain all statics (globals, classes, …) that have been defined in your Dart program (and haven’t been tree-shaken away). We call them “global objects”.

There is some history here: initially we had only one global object which was on the top-level of JS. We didn’t want (and still don’t want to) pollute JavaScript’s global namespace and restrained ourselves to one object. We didn’t just wrap the program into an anonymous function because that slowed down the program.

Things evolved… JavaScript engines became faster with nested scopes and we moved our code into an anonymous function. That made it possible to switch to more “top level” (wrapped in a function) objects. Also we discovered that JS engines are very bad with object that contain too many properties. As a consequence we cut the one global object into smaller pieces, and distribute the compiled statics/classes into different global objects. Where Dart classes end up is based on a predefined map for internal libraries, and based on their library name for others.

We don’t just run up to a certain number (say 1000 for “A”, 1000 for “B”, …), because that would mean that the JS output could change significantly when doing minor changes.

We could now just get rid of these objects, but we haven’t seen the need for it yet. JS engines are very good at optimizing object accesses. I haven’t tested it, but I think that using two functions of the same object is probably faster or as fast as using two local variables.

Answered By – Florian Loitsch

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *