Simple Javscript scope example

A simple demonstration of how Javascript behaves like Lisp, even though it looks like C. Anonymous (lambda) functions provide some additional variable scopes with Lisp-like results.

by thirdender

HTML

<script src="http://requirejs.org/docs/release/2.0.4/minified/require.js"></script>
<xmp></xmp>

CSS

xmp {
  margin: 1em;
}

JavaScript

var xmp = $("xmp");
function output(str) {
  xmp.append(str + "\n");
}

// Here we move the scope of the variable up one level, but not to the global
// scope. The variable stays in our own anonymous function.
(function() {
  var a;
  requirejs([], function() {
    a = "Monkeys";
  });
  // Disclaimer: RequireJS is an asynchronous system. Typically speaking, you
  // would be unable to access the variable 'a' again so soon, but we're
  // passing an empty array to load into RequireJS, so the callback happens
  // immediately.
  output("a: " + a);
})();

// Here we see that the variable 'a' no longer exists. Because the anonymous
// function that acted as its closure is finished, the variable is gone, and
// we get an error when trying to access it.
try {
  output("a: " + a);
} catch(e) {
  output("Error: " + e);
}

// Now we're going to see what happens when we keep two copies of a variable
// with the same name in two different nested scopes.
(function() {
  var a;
  requirejs([], function() {
    var a = "Monkeys";
  });
  // Here the function outputs undefined as the value of 'a'. The reason is
  // that it was never defined in this scope. The RequireJS callback was its
  // own scope, and the variable 'a' inside that scope replaced the "original"
  // variable 'a'. After the callback was completed, the scope popped off the
  // stack, and the "original" variable 'a' came back into existence with its
  // original value (undefined).
  output("a: " + a);
})();