tech

JS API Design Thoughts

This is probably one of the wierdest things I had to wrap my head around Javascript recently. It’s a combination of how closures work, functions being first class objects and that you can add properties into objects.

Consider this function foo():

function foo() {
  function boo() {
    this.goo();
  }
}

Now, logically if you run the code like so:

let f = new foo();
f.boo(); // this won't run

f.boo() will give an error, naturally. There is really no reason to expect that goo() exists…unless someone ‘injects’ goo into boo somehow like so:

let f = new foo();
f.boo.goo = function() {
  console.log("Hello");
}
f.boo(); // now this will run

At a glance, one might say that this seems dangerous, not useful, etc. Well, I haven’t really thought much about it’s implications, but it does suggest interesting approaches to API design that might not be possible in other languages.

The game engine Phaser 3 does this: it takes in an object and injects properties into its preload(), update() and create() functions.

For brevity, we will just talk about the preload() function.

const game = new Phaser.Game({
  scene: { 
    preload() {
      // this.add technically does not exist
      // but Phaser will inject it upon 
      // initialization apparently...
      this.add.graphics(...); 
    }
  } 
})

This becomes interesting when we use closures like so:

// Create a function foo() that has the preload() function, which
// Phaser will inject more properties into.
function foo() {
  let x = 10;
  let y = 20;

  function preload() {
    // Again, this.add will be avaliable
    // not within this class but later!
    //
    // Note that this function when called
    // at a later point will have access to
    // new properties like this.add, as well 
    // as x and y!!
    this.add.graphics(x, y);
  }

  return { preload };
}

const game = new Phaser.Game({
  scene: foo
})

Now we can not only use properties injected into our preload() function, but we also have access to our own variables x and y.

Personally, as much as I hate javascript, I think this property of javascript is interesting to talk about.

Whether I will eventually like it or not in practice…time will tell. For now, I do not immediately hate it, and I already hate a lot of things in javascript!