Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

Variable hoisting

console.log(hoist); // Output: undefined

var hoist = 'The variable has been hoisted.';
function hoist() {
  console.log(message); // Output: undefined
  var message='Hoisting is all the rage!'
}

hoist();
function hoist() {
  a = 20;
  var b = 100;
}

hoist();

console.log(a); 
/* 
Accessible as a global variable outside hoist() function
Output: 20
*/

console.log(b); 
/*
Since it was declared, it is confined to the hoist() function scope.
We can't print it out outside the confines of the hoist() function.
Output: ReferenceError: b is not defined
*/

This means that, all undeclared variables are global variables.

In EcmaScript2015(ES6), let and const are hoisted but not initialized.

console.log(x); // Cannot access 'x' before initialization
let x = 10;

Function hoisting

hoisted(); // Output: "This function has been hoisted."

function hoisted() {
  console.log('This function has been hoisted.');
};

Function expressions, however are not hoisted.

expression(); //Output: "TypeError: expression is not a function

var expression = function() {
  console.log('Will this work?');
};
var text = 'outside';

function print(){
    console.log(text);
    var text = 'inside';
};
print(); // Output: undefined, as only declaration was hoisted, no initialization happened.

References: