Deep Dive into JavaScript Closures: A Practical Approach

Learning a new language involves a series of steps, whereas mastering a new language is the product of patience, practice, mistakes and experience.

Some developers will have enough knowledge to provide features based on customer needs, but to be a good developer it takes more than that.

A good developer is one who takes time to come back and have a good grasp of the basic/core concepts of the language.

Today we delve into javascript closures and hope what you have learned will benefit your project.

Deep Dive into JavaScript Closures: A Practical Approach

What is a javascript closure?

JavaScript closures are when the inner function can access members of the outer function (lexical scope even when executed outside the scope of the outer function.

So we can't talk about closures, and at the same time not fulfilling the function and scope.

scope in javascript

Scope refers to the degree of visibility of variables defined in a program. There are ways to create scopes in javascript: try-catch blocksfunctions, let keywordand others in curly braces. We have mainly two different scopes: global scope and local scope.

var initialBalance = 0
// Global Scopefunction deposit (amount)
{ /** * Local Scope * Code here has access to anything declared in the global scope */
var newBalance = parseInt(initialBalance) + parseInt(amount) return newBalance}

Every function in JavaScript creates its own local scope when declared.

This means that nothing declared in the function's local scope can't be accessed from outside. Consider the following instructions:

var initialBalance = 300
// Variable declared in the Global Scopefunction withdraw (amount)
{was balance
// Variable declared in function scope balance = parseInt(initialBalance) - parseInt(amount)
return balance}console.log(initialBalance)
// Will output initialBalance value as it is declared in the global scopeconsole.log(balance)
// ReferenceError: Can't find variable: balance

Lexical scope

The lexical scope of JavaScript is in the compilation phase. It sets the scope of the variable so that it can only be called/referenced from the block of code in which it is defined.

A function declared in a surrounding function block can access variables within the lexical scope of the surrounding function.

var initialBalance = 300
// Global Scopefunction withdraw (amount)
{ /** * Local Scope * Code here has access to anything declared in the global scope */
var balance = parseInt(initialBalance) - parseInt(amount) const actualBalance = (function ()
{ const TRANSACTIONCOST = 35 return balance - TRANSACTIONCOST /
** * Accesses balance variable from the lexical scope */ })()
// Immediately Invoked Function expression. IIFE
// console.log(TRANSACTIONCOST)
// ReferenceError: Can't find variable: TRANSACTIONCOST return actualBalance}

Calls an inner function outside of its enclosing function, but still maintains access to variables in its enclosing function (lexically scoped), creating a javascript closure.

function person ()
{ var name = 'Paul'
// Local variable var actions = { speak: function ()
{ // new function scope console.log('My name is ', name)
/** * Accessing the name variable from the outer function scope (lexical scope) */ } }
// actions object with a function return actions
/** * We return the actions object * We then can invoke the speak function outside this scope */}
person().speak() // Inner function invoked outside its lexical Scope

Closures allow us to expose an interface while hiding and saving the execution context in the outer scope.

Some javascript design patterns use closures.

module mode

One of the well-implemented patterns is the module pattern, which allows you to emulate: private, public, and privileged members.

var Module = (function ()
{ var foo = 'foo' // Private Property function addToFoo (bam)
{ // Private Method foo = bam return foo }
var publicInterface = { bar: function ()
{ // Public Method return 'bar' }, bam: function ()
{ // Public Method return addToFoo('bam') // Invoking the private method } }
return publicInterface // Object will contain public methods})()Module.bar() // barModule.bam() // bam

According to the module pattern description above, only public methods and properties in the returned object can be used outside the execution context of the closure.

All private members still exist because their execution context is preserved but hidden in the outer scope.

More illustrations on closures

When we pass a function to setTimeoutor any kind of callback. The function still remembers the lexical scope due to the action of the closure function.

function foo () { var bar = 'bar' setTimeout(function () { console.log(bar) }, 1000)}foo() // bar

Closures and loops

for (var i = 1; i <= 5; i++)
 { (function (i) { setTimeout(function ()
 { console.log(i) }, i * 1000) })
(i)}/*** Prints 1 thorugh 5 after each second* Closure enables us to remember the variable i* An IIFE to pass in a new value of the variable i for each iteration* IIFE (Immediately Invoked Function expression)*/
for (let i = 1; i <= 5; i++) { (function (i) { setTimeout(function () { console.log(i) }, i * 1000) })(i)}/*** Prints 1 through 5 after each second* Closure enabling us to remember the variable i* The let keyword rebinds the value of i for each iteration*/

I bet we now understand closures and can do the following:

  • Demonstrate a use case for it or identify it in a context where we never knew we were using it.
  • Maintain the execution context as we wish
  • Implement code in javascript module pattern
  • Use closures in our code, clearly understand

  Join Xiaobian's front-end learning qun to receive high-quality front-end free learning course videos, and I will share high-quality materials for you.

        213+126+486 Invitation Code: Fallen Leaves

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325430799&siteId=291194637