are lexically scoped at a function level, while ones with let or const have a block level scope. Since declarations are processed before any code is executed, a variable can be assigned to and used prior to being declared in the code. This is referred to as , and it is equivalent to variables being forward declared at the top of the function or block. With var, let, and const statements, only the declaration is hoisted; assignments are not hoisted. Thus a statement in the middle of the function is equivalent to a declaration statement at the top of the function, and an assignment statement at that point in the middle of the function. This means that values cannot be accessed before they are declared; forward reference is not possible. With var a variable's value is undefined until it is initialized. Variables declared with let or const cannot be accessed until they have been initialized, so referencing such variables before will cause an error. Function declarations, which declare a variable and assign a function to it, are similar to variable statements, but in addition to hoisting the declaration, they also hoist the assignment – as if the entire statement appeared at the top of the containing function – and thus forward reference is also possible: the location of a function statement within an enclosing function is irrelevant. This is different from a function expression being assigned to a variable in a var, let, or const statement. So, for example, var func = function() { .. } // declaration is hoisted only function func() { .. } // declaration and assignment are hoisted Block scoping can be produced by wrapping the entire block in a function and then executing it – this is known as the immediately-invoked function expression pattern – or by declaring the variable using the let keyword. Declaration and assignment Variables declared outside a scope are global. If a variable is declared in a higher scope, it can be accessed by child scopes. When JavaScript tries to resolve an identifier, it looks in the local scope. If this identifier is not found, it looks in the next outer scope, and so on along the scope chain until it reaches the global scope where global variables reside. If it is still not found, JavaScript will raise a ReferenceError exception. When assigning an identifier, JavaScript goes through exactly the same