Understanding the scoping rules of JavaScript is one of the fundamental things to learn when getting started with
the language. I just found this link posted
by @codylindley on Twitter. It goes over some basic principles of
jQuery, however the first part covers native JavaScript scoping. It is an interesting example to get an understanding
about it.
Take the following piece of JavaScript:
var x = "Hi";
var someFunction = (function(){
document.getElementById("out").innerHTML = x;
});
someFunction();
The
example is quite simple. There is
x
, which is defined in the global scope, followed by the definition of a
function which gets stored in the
someFunction
variable.
someFunction
gets called immediately
afterwards, printing out the value of
x
to the HTML element "out". When executed, we get "Hi" as a result.
Why
does this happen? In order to understand this, you need to understand that JavaScript has
function scope,
meaning that when printing out x, it will first search for a definition within the function itself, and then it will
walk up the prototype chain in order to find a corresponding variable definition. In the specific example above, it
will go up till it reaches the global (window) object where x is defined.
If now the example above gets
modified as follows, can you guess what will be its output??
var x = "Hi";
var someFunction = (function(){
document.getElementById("out").innerHTML = x;
var x = "Hi, there!";
});
someFunction();
Actually
the output is "undefined". This is due to the
lexical function scoping, meaning the scoping rules are applied at
function-definition, not at runtime. Btw, this kind of mechanism also allows for having
closures.
Hence, x is defined within the function's scope, but just not at the moment when it was printed out.
To fix
this one would have to explicitly let x point to the globally defined one like
var x = "Hi";
var someFunction = (function(){
document.getElementById("out").innerHTML = window.x;
var x = "Hi, there!";
});
someFunction();
Now
it again works.
Questions? Thoughts? Hit me up
on Twitter