In hoisting, javascript moves all declaration of variables, function to top as per their scope. Hoisting is javascript default behavior and done during compilation process and allows to use all variables, function in their declared scope.

In javascript, only declarations are hoisted not initializations.

By default variable value without initialization is undefined, because javascript assigns undefined to uninitialized variable.

<script>
 document.write(n);  //ReferenceError: n is not defined
</script> 

Variable n is used directly without initialization or declaration in above example. So, javascript gives ReferenceError.

<script>
 document.write(n);  //outputs undefined
 n = "javascript";
</script> 

Above example gives output undefined. because, first we output variable n and then assigns a string value.

Why it outputs undefined

Because by default uninitialized variable is assigned undefined by javascript.

After Javascript hoisting of above example, Below is the hoisted code.

<script>
 var n; // Javascript declares variable after hoisting
 document.write(n);  //outputs undefined
 n = "javascript";
</script>

After Initialization of variable

<script>
 n = "javascript";
 document.write(n);  
</script> 

It outputs javascript, because javascript declares variable first with hoisting and assign value and then output it, like below example

<script>
 var n; // javascript declares variable first.
 n = "javascript";
 document.write(n);  
</script> 

Function scoped variable

<script>
function test() {
  document.write(n); // outputs undefined
  var n = 'javascript';
}
test();
document.write(n);   // ReferenceError: n is not defined
</script> 

var n is initialized after document.write, so javascript hoist var n but do not initialized it. hence it outputs undefined and because of function scope of var n, it is only accessible inside function test(), accessing outside gives ReferenceError.

Hoisting with let

<script>
  document.write(a);  // ReferenceError: Cannot access 'a' before initialization
  let a = "javascript";
</script>

with let variable, After ES6, let variable needs to initialized first before use. Without initialization it gives ReferenceError

Hoisting with const

<script>
 document.write(a);  // ReferenceError:  Cannot access 'a' before initialization
 const a = "javascript";
</script>

const variable needs to declared and initialize first. In above example. const variable is declared after document.write(a), Hence it gives ReferenceError.

Function Hoisting

<script>
  test(); 
 function test() {
  document.write("Hoisted function");  
 };
</script>

Above function test() will run without any error, because javascript moves function declaration at the top, see below example.

<script>
  // javascript moves function declaration to the top
 function test() {
  document.write("Hoisted function");  
 };

 test(); 
</script>