Unfortunately valid JavaScript
Published 2015-2-13The 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
Did I make your day?
Buy me a coffee
(you can learn about the bigger picture I'm working towards on my patreon page )