Monday, August 5, 2019

Understanding closure in Javascript



I'm trying to wrap my head around closures in Javascript.



Here is an example from a tutorial:



function greeter(name, age) {
var message = name + ", who is " + age + " years old, says hi!";


return function greet() {
console.log(message);
};
}

// Generate the closure
var bobGreeter = greeter("Bob", 47);

// Use the closure
bobGreeter();



The author said that this is an effective way of using closure to make private variables, but I don't get the point.



Could someone enlighten the benefits of coding like this?


Answer



A closure is a pair of a function and the environment in which it was defined (assuming lexical scoping, which JavaScript uses). Thus, a closure's function can access variables in its environment; if no other function has access to that environment, then all of the variables in it are effectively private and only accessible through the closure's function.



The example you provided demonstrates this reasonably well. I've added inline comments to explain the environments.




// Outside, we begin in the global environment.
function greeter(name, age) {
// When greeter is *invoked* and we're running the code here, a new
// environment is created. Within this environment, the function's arguments
// are bound to the variables `name' and `age'.

// Within this environment, another new variable called `message' is created.
var message = name + ", who is " + age + " years old, says hi!";

// Within the same environment (the one we're currently executing in), a

// function is defined, which creates a new closure that references this
// environment. Thus, this function can access the variables `message', `name',
// and `age' within this environment, as well as all variables within any
// parent environments (which is just the global environment in this example).
return function greet() { console.log(message); };
}


When var bobGreeter = greeter("Bob", 47); is run, a new closure is created; that is, you've now got a new function instance along with the environment in which it was created. Therefore, your new function has a reference to the `message' variable within said environment, although no one else does.




Extra reading: SICP Ch 3.2. Although it focuses on Scheme, the ideas are the same. If you understand this chapter well, you'll have a good foundation of how environments and lexical scoping work.



Mozilla also has a page dedicated to explaining closures.


No comments:

Post a Comment

hard drive - Leaving bad sectors in unformatted partition?

Laptop was acting really weird, and copy and seek times were really slow, so I decided to scan the hard drive surface. I have a couple hundr...