Javascript's Hidden Treasures 

what javascript actually is

what people think javascript is

Closures

What exactly are closures?

  • A closure is a function that has access to the parent scope, even after the scope has closed.

 

  • A closure is the combination of a function and the lexical environment within which that function was declared.

First we  understand scope in JavaScript.

 

  • Scope is essentially the lifespan of a variable in JavaScript. You see, where a variable is defined plays a large role in how long that variable is around, and which functions in your program have access to it.

Locally scoped variable

Globally scoped variable

/ Example of accessing variables INSIDE the function
// words is a LOCAL variable
function speak(){
  var words = 'hi'; 
  console.log(words);
}
speak(); // 'hi'
console.log(words); // Uncaught ReferenceError: words is not defined
// Example of accessing variables OUTSIDE the function
// words is a GLOBAL variable
var words = 'hi';
function speak(){ 
  console.log(words);
}
speak(); // 'hi' 
console.log(words); // 'hi'

Closures in Nested Functions

function speak() {
  return function logIt() {
    var words = 'hi';
    console.log(words);
  }
}

A closure is a function that has access to the parent scope, even after the scope has closed.

function speak() {
  var words = 'hi';
  return function logIt() {
    console.log(words);
  }
}

Closures basically allow us to do 3 things

  • We can refer to variables defined outside of the current function.
  • Inner functions can refer to variables defined in outer functions even after the latter have returned.
  • Inner functions store their outer function’s variables by reference, not by value.

Hoisting in Javascript

When people first encounter Hoisting in Javascript

Hoisting is employed to explain how Variables and Function declarations are ‘lifted’ to the top of a function or a global scope.

So what is Hoisting?

An example of hoisting

console.log(notyetdeclared);

var notyetdeclared = "now it is declared";

hoisting();

function hoisting() {


  console.log(notyetdeclared);

  var notyetdeclared = "declared differently";

  console.log(notyetdeclared);

  
}

A call stack for the code sample

Lexical environments for the code sample

So to elaborate on the first phase:  It works in two steps.

  1. The current code is ‘scanned’ for function declarations. Function expressions and arrow functions are skipped. For every function that is discovered a new function is created and bound to the environment with the function’s name. If the identifier name already exists, its value is overwritten.​
  2. Then the current environment is scanned for variables. Variables defined with var and placed outside other functions are found and an identifier is registered with its value initialized to undefined. If an identifier exists, the value is left untouched.

Questions?

Closures and Hoisting

By Prameet Chakarborty

Closures and Hoisting

  • 461