Because all our global declarations are already registered in memory during compilation and prior to runtime, we can access these declarations anywhere in our code, even before they formally have been declared.
//we can use these variables even though they haven't formally been declared yet in this scope
console.log(a === b) // true
console.log(b === c) // true
console.log(c === d) // true
// ReferenceError is thrown. We never declared this, so it's not registered in memory during compilation
console.log(e)
const a = 'foo'
const b = 12345
const c = false
const d = { bar: 'hey' }This looks odd at first. Because these variables are ready to use but haven't yet been bound to any value, they're all undefined, and so they're all equal to each other.
Note that trying to log a value (e) that we never formally declare in our code will throw a ReferenceError since we never registered this variable in memory during compilation.
What about calling functions before they're formally declared in the code?
foo() // works! logs 'hello from foo'
bar() // ReferenceError: internal const f isn't in global scope, so it isn't registered in memory yet
baz() // TypeError: baz is not a function (not yet, anyway, but it's already in memory)
function foo() {
console.log('hello from foo')
}
function bar() {
console.log(f)
const f = 'hello from bar'
}
const baz = () => console.log('hello from baz')Calling function foo works because this function is bound to the variable foo at compilation (a benefit of using the function keyword to declare the function) and is ready to use at runtime.
Calling function bar almost works for the same reason, but because it contains internal variable declarations that need to be registered in memory, and because these declarations aren't made in the global scope, the runtime doesn't know what f is yet and is trying to reference a variable that doesn't exist, causing a ReferenceError to be thrown.
Calling baz doesn't work, even though it's in global scope and is therefore a registered value in memory. Unfortunately, it's only later bound to its function value during runtime, so when we try calling it at the top of the global scope, it has no value -- not even undefined. We would get ReferenceError: Cannot access 'baz' before initialization.