Q:

What is the logic behind when JavaScript throws a ReferenceError?

I've been using JavaScript for years but have been trying to increase my deep, under-the-hood type knowledge of the language lately.  I'm a bit confused about what the logic is behind when JavaScript throws a ReferenceError.
For example, none of these throw a referenceError, but still write undefined to the console:
function foobar(foo)
{
    var bar = foo;
    console.log(bar);
}
foobar();

or
var foo = undefined;
var bar = foo;
console.log(bar);

or
var foo;
var bar = foo;
console.log(bar);

but this obviously does throw a ReferenceError error on the first line without writing to the console:
var bar = foo;
console.log(bar);

So it seems that having a variable in a parameter list or declaring it will stop a referenceError from being thrown - even though the variable is still 'undefined'.
Does anyone know what's going on under the hood or what the hard and fast rules are surrounding this? Does anyone know why these aren't considered referenceErrors?

A:

There's a difference in using a variable that exists but has an undefined value, and using a variable that doesn't exist and was never declared.
The latter will create a reference error as you're trying to reference something that doesn't exists and has not been declared.
On the other hand, when you do 
var foo;

foo does exists, and it has been declared, it's value is just undefined, so you can still reference it without throwing an error.
In other words, trying to reference a variable that hasn't been declared will throw a reference error, while referencing declared variables will never throw a reference error, regardless of wether or not a value has been set for that variable.

