Annotated source; I'm assuming this code starts out at global scope:
var local = true;      // Creates a global variable called `local`
function outer() {
    /* local scope */
    var local = false; // Creates a local `local` within `outer`, shadowing (hiding) the global
    function inner() {
      alert(local);    // alerts "undefined", the value of `inner`'s `local`
      var local;       // Creates a local `local` within `inner`, shadowing (hiding) `outer`'s version
    }
    inner();
}
outer();
function a(x) {        // Creates a global function `a`
    return x * 2;
}
var a;                 // Has no effect
alert(a);              // alerts the function source (on engines that have it)
There are basically three things at work in the code above:
- A declaration in a nested scope shadows (hides) a declaration in a containing scope. So the - localin- outershadows the global, and the- localin- innershadows- outer's- local.
 
- vardeclarations are processed when execution enters an execution context, not where they appear in the source code. They're sometimes said to be "hoisted" because they are effectively moved up (raised, hoisted) to the top of the context in which they occur. (More: Poor misunderstood- var) This effect is particularly noticeable within the- innerfunction, because the- localbeing alerted is the one from- inner, not the one from- outer(which is why it's- undefined), even though the declaration is underneath the alert.
 
- Function declarations create a symbol in the scope in which they're defined, in the same symbol space as - vardeclarations do. (Specifically, they both create entries in the binding object of the lexical environment of the execution context in which they occur.) So if you have a function declaration and a- varwith the same name (as you do with- aat the end of your code), there's a conflict. Which wins? The function declaration wins, because of the order dictated by §10.5 of the specification, which says that function declarations occur before- vardeclarations, and that a- varfor a symbol that's already defined doesn't override it.