Understanding Closure in Javascript

Consider this example:

function onePiece(name){
  var message = 'King of the Pirates';
  return function greeting() {
    console.log(message +' '+ name)
  }
}

Here we have function onePiece that takes a parameter. It returns a function nested inside it i.e it returns function greeting.

Variable message is declared inside function onePiece which means variable message is in function onePiece scope.

Function greeting has access to variable message and parameter because nested function can access parameter  and any variable declared in its parent/outer scope (lexical scope).

onePiece('luffy');
ƒ greeting() {
    console.log(message +' '+ name)
}

It returns function greeting(definition of function greeting).

This might look little complicate but it is not. This is similar to code example below:

function fruit(){
  return 'apple';
}
fruit();    // apple

Here, when we invoke function fruit, it returns string(apple) where as function onePiece returns function(function greeting) when invoked.

Here we are invoking function onePiece and assigning the value it returns to variable anime i.e we are assigning function greeting to variable anime.

var anime = onePiece('Luffy');
console.log(anime) ;
ƒ greeting() {
    console.log(message +' '+ name)
  }

So when we invoke anime(), we are invoking function greeting.

The question is does function greeting still have access to the parameter and variable declared in function onePiece scope? Because now function greeting is executed outside function onePiece, it’s declared lexical scope. And remember function onePiece is already executed(invoked).

Answer is yes. Because of Closure.

anime();
//King of the Pirates Luffy

Closure is when nested function can still access the variable declared in its parent/outer enclosing scope even when it is invoked outside its parent function(lexical environment)