The Problem - Cognitive Dissonance

When writing JavaScript you have to find a balance between writing in a way that is expressive and easy to read and writing without creating cognitive dissonance between the program you wrote and the program that actually runs.

Exhibit A - Unfortunately valid JavaScript

This is a terrible program and has all sorts of errors that should be detected and halted well-before runtime but, unfortunately, it's perfectly valid.

var a = 1
 
y = 4
z = "hello";
 
function add(oneThing, twoThing) {
  return
  "redThing, blueThing (" + (oneThing + twoThing) + ")";
}
 
var b = 7;
 
add(16, 17);
 
var x = 42
 
console.log(add(x, b));
 
var x = 43;

Here's that same program as we can imagine it to be rewritten by the JS interpreter (parsed, tokenized, rendered as AST, etc):

// Declarations
var global // internal
  , add
  , a
  , b
  , x
  ;
 
// Global & Literal Function Initializations
global = new Function("return this;")();
add = function (oneThing, twoThing) {
  return;
  // This stuff is straight-up dropped
  // "redThing, blueThing (" + (oneThing + twoThing) + ")";
};
global.y = 4;
global.z = "hello";
 
 
// Executable Code (including non-function initializations)
a = 1;
 
b = 7;
 
add(16, 17);
 
x = 42;
 
console.log(add(x, b));
 
x = 43;

Exhibit B - Reasonable JavaScript

Here's a rendering of what the imaginary author of the prior example probably would have intended:

(function () {
  "use strict";
 
  //
  // Declarations and Initializations
  //
  function add(oneThing, twoThing) {
    return "redThing, blueThing (" + (oneThing + twoThing) + ")";
  }
 
  var a = 1;
  var b = 7;
  var x = 42;
 
  //
  // Executable Code
  //
  add(16, 17);
 
  console.log(add(x, b));
 
  x = 43;
 
  console.log(add(x, b));
 
}());

And here's what that JavaScript would look like after being parsed, tokenized, etc:

var __anonymous_reference__
  ;
  
__anonymous_reference__ = function () {
  "use strict";
 
  var add
    , a
    , b
    , x
    ;
  
  add = function (oneThing, twoThing) {
    return "redThing, blueThing (" + (oneThing + twoThing) + ")";
  };
  a = 1
  b = 7
  x = 42
 
  add(16, 17);
 
  console.log(add(x, b));
 
  x = 43;
 
  console.log(add(x, b));
};
 
__anonymous_reference__();

Notes

  • Function Literals are hoisted and evaluated at the hoist

Conclusion

Try to write code that is similar to code that is actually run so that you're not expecting one thing and getting another.


By AJ ONeal

If you loved this and want more like it, sign up!


Did I make your day?
Buy me a coffeeBuy me a coffee  

(you can learn about the bigger picture I'm working towards on my patreon page )