Lexical Scope & Closures [duplicate] - javascript
What is a brief introduction to lexical scoping?
I understand them through examples. :)
First, lexical scope (also called static scope), in C-like syntax:
void fun()
{
int x = 5;
void fun2()
{
printf("%d", x);
}
}
Every inner level can access its outer levels.
There is another way, called dynamic scope used by the first implementation of Lisp, again in a C-like syntax:
void fun()
{
printf("%d", x);
}
void dummy1()
{
int x = 5;
fun();
}
void dummy2()
{
int x = 10;
fun();
}
Here fun can either access x in dummy1 or dummy2, or any x in any function that call fun with x declared in it.
dummy1();
will print 5,
dummy2();
will print 10.
The first one is called static because it can be deduced at compile-time, and the second is called dynamic because the outer scope is dynamic and depends on the chain call of the functions.
I find static scoping easier for the eye. Most languages went this way eventually, even Lisp (can do both, right?). Dynamic scoping is like passing references of all variables to the called function.
As an example of why the compiler can not deduce the outer dynamic scope of a function, consider our last example. If we write something like this:
if(/* some condition */)
dummy1();
else
dummy2();
The call chain depends on a run time condition. If it is true, then the call chain looks like:
dummy1 --> fun()
If the condition is false:
dummy2 --> fun()
The outer scope of fun in both cases is the caller plus the caller of the caller and so on.
Just to mention that the C language does not allow nested functions nor dynamic scoping.
Lets try the shortest possible definition:
Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.
That is all there is to it!
var scope = "I am global";
function whatismyscope(){
var scope = "I am just a local";
function func() {return scope;}
return func;
}
whatismyscope()()
The above code will return "I am just a local". It will not return "I am a global". Because the function func() counts where is was originally defined which is under the scope of function whatismyscope.
It will not bother from whatever it is being called(the global scope/from within another function even), that's why global scope value I am global will not be printed.
This is called lexical scoping where "functions are executed using the scope chain that was in effect when they were defined" - according to JavaScript Definition Guide.
Lexical scope is a very very powerful concept.
Lexical (AKA static) scoping refers to determining a variable's scope based solely on its position within the textual corpus of code. A variable always refers to its top-level environment. It's good to understand it in relation to dynamic scope.
Scope defines the area, where functions, variables and such are available. The availability of a variable for example is defined within its the context, let's say the function, file, or object, they are defined in. We usually call these local variables.
The lexical part means that you can derive the scope from reading the source code.
Lexical scope is also known as static scope.
Dynamic scope defines global variables that can be called or referenced from anywhere after being defined. Sometimes they are called global variables, even though global variables in most programmin languages are of lexical scope. This means, it can be derived from reading the code that the variable is available in this context. Maybe one has to follow a uses or includes clause to find the instatiation or definition, but the code/compiler knows about the variable in this place.
In dynamic scoping, by contrast, you search in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call stack. "Dynamic" refers to change, in that the call stack can be different every time a given function is called, and so the function might hit different variables depending on where it is called from. (see here)
To see an interesting example for dynamic scope see here.
For further details see here and here.
Some examples in Delphi/Object Pascal
Delphi has lexical scope.
unit Main;
uses aUnit; // makes available all variables in interface section of aUnit
interface
var aGlobal: string; // global in the scope of all units that use Main;
type
TmyClass = class
strict private aPrivateVar: Integer; // only known by objects of this class type
// lexical: within class definition,
// reserved word private
public aPublicVar: double; // known to everyboday that has access to a
// object of this class type
end;
implementation
var aLocalGlobal: string; // known to all functions following
// the definition in this unit
end.
The closest Delphi gets to dynamic scope is the RegisterClass()/GetClass() function pair. For its use see here.
Let's say that the time RegisterClass([TmyClass]) is called to register a certain class cannot be predicted by reading the code (it gets called in a button click method called by the user), code calling GetClass('TmyClass') will get a result or not. The call to RegisterClass() does not have to be in the lexical scope of the unit using GetClass();
Another possibility for dynamic scope are anonymous methods (closures) in Delphi 2009, as they know the variables of their calling function. It does not follow the calling path from there recursively and therefore is not fully dynamic.
A lexical scope in JavaScript means that a variable defined outside a function can be accessible inside another function defined after the variable declaration. But the opposite is not true; the variables defined inside a function will not be accessible outside that function.
This concept is heavily used in closures in JavaScript.
Let's say we have the below code.
var x = 2;
var add = function() {
var y = 1;
return x + y;
};
Now, when you call add() --> this will print 3.
So, the add() function is accessing the global variable x which is defined before method function add. This is called due to lexical scoping in JavaScript.
Lexical scope means that in a nested group of functions, the inner functions have access to the variables and other resources of their parent scope.
This means that the child's functions are lexically bound to the execution context of their parents.
Lexical scope is sometimes also referred to as static scope.
function grandfather() {
var name = 'Hammad';
// 'likes' is not accessible here
function parent() {
// 'name' is accessible here
// 'likes' is not accessible here
function child() {
// Innermost level of the scope chain
// 'name' is also accessible here
var likes = 'Coding';
}
}
}
The thing you will notice about lexical scope is that it works forward, meaning the name can be accessed by its children's execution contexts.
But it doesn't work backward to its parents, meaning that the variable likes cannot be accessed by its parents.
This also tells us that variables having the same name in different execution contexts gain precedence from top to bottom of the execution stack.
A variable, having a name similar to another variable, in the innermost function (topmost context of the execution stack) will have higher precedence.
Source.
I love the fully featured, language-agnostic answers from folks like #Arak. Since this question was tagged JavaScript though, I'd like to chip in some notes very specific to this language.
In JavaScript our choices for scoping are:
as-is (no scope adjustment)
lexical var _this = this; function callback(){ console.log(_this); }
bound callback.bind(this)
It's worth noting, I think, that JavaScript doesn't really have dynamic scoping. .bind adjusts the this keyword, and that's close, but not technically the same.
Here is an example demonstrating both approaches. You do this every time you make a decision about how to scope callbacks so this applies to promises, event handlers, and more.
Lexical
Here is what you might term Lexical Scoping of callbacks in JavaScript:
var downloadManager = {
initialize: function() {
var _this = this; // Set up `_this` for lexical access
$('.downloadLink').on('click', function () {
_this.startDownload();
});
},
startDownload: function(){
this.thinking = true;
// Request the file from the server and bind more callbacks for when it returns success or failure
}
//...
};
Bound
Another way to scope is to use Function.prototype.bind:
var downloadManager = {
initialize: function() {
$('.downloadLink').on('click', function () {
this.startDownload();
}.bind(this)); // Create a function object bound to `this`
}
//...
These methods are, as far as I know, behaviorally equivalent.
In simple language, lexical scope is a variable defined outside your scope or upper scope is automatically available inside your scope which means you don't need to pass it there.
Example:
let str="JavaScript";
const myFun = () => {
console.log(str);
}
myFun();
// Output: JavaScript
Lexical scope means that a function looks up variables in the context where it was defined, and not in the scope immediately around it.
Look at how lexical scope works in Lisp if you want more detail. The selected answer by Kyle Cronin in Dynamic and Lexical variables in Common Lisp is a lot clearer than the answers here.
Coincidentally I only learned about this in a Lisp class, and it happens to apply in JavaScript as well.
I ran this code in Chrome's console.
// JavaScript Equivalent Lisp
var x = 5; //(setf x 5)
console.debug(x); //(print x)
function print_x(){ //(defun print-x ()
console.debug(x); // (print x)
} //)
(function(){ //(let
var x = 10; // ((x 10))
console.debug(x); // (print x)
print_x(); // (print-x)
})(); //)
Output:
5
10
5
Lexical scoping: Variables declared outside of a function are global variables and are visible everywhere in a JavaScript program. Variables declared inside a function have function scope and are visible only to code that appears inside that function.
IBM defines it as:
The portion of a program or segment unit in which a declaration
applies. An identifier declared in a routine is known within that
routine and within all nested routines. If a nested routine declares
an item with the same name, the outer item is not available in the
nested routine.
Example 1:
function x() {
/*
Variable 'a' is only available to function 'x' and function 'y'.
In other words the area defined by 'x' is the lexical scope of
variable 'a'
*/
var a = "I am a";
function y() {
console.log( a )
}
y();
}
// outputs 'I am a'
x();
Example 2:
function x() {
var a = "I am a";
function y() {
/*
If a nested routine declares an item with the same name,
the outer item is not available in the nested routine.
*/
var a = 'I am inner a';
console.log( a )
}
y();
}
// outputs 'I am inner a'
x();
I hope this is helpful, here is my attempt at a slightly more abstract definition:
Lexical scope:
The access or range something (e.g. a function or variable) has to other elements in the program as determined by its position in the source code.
Fwiw, my logic here simply builds from the definitions of:
Lexical: relating to the words or vocabulary of a language (specifically the word as separate from it's grammar or construction) {in our case - a programming language}.
Scope (noun): the range of operation {in our case the range is: what can be accessed}.
Note, the original 1960 definition of Lexical Scope from the ALGOL 60 spec is far more pithy than my attempt above:
Lexical scope: the portion of source code in which a binding of a name with an entity applies. source
Lexical scope refers to the lexicon of identifiers (e.g., variables, functions, etc.) visible from the current position in the execution stack.
- global execution context
- foo
- bar
- function1 execution context
- foo2
- bar2
- function2 execution context
- foo3
- bar3
foo and bar are always within the lexicon of available identifiers because they are global.
When function1 is executed, it has access to a lexicon of foo2, bar2, foo, and bar.
When function2 is executed, it has access to a lexicon of foo3, bar3, foo2, bar2, foo, and bar.
The reason global and/or outer functions do not have access to an inner functions identifiers is because the execution of that function has not occurred yet and therefore, none of its identifiers have been allocated to memory. What’s more, once that inner context executes, it is removed from the execution stack, meaning that all of it’s identifiers have been garbage collected and are no longer available.
Finally, this is why a nested execution context can ALWAYS access it’s ancestors execution context and thus why it has access to a greater lexicon of identifiers.
See:
https://tylermcginnis.com/ultimate-guide-to-execution-contexts-hoisting-scopes-and-closures-in-javascript/
https://developer.mozilla.org/en-US/docs/Glossary/Identifier
Special thanks to #robr3rd for help simplifying the above definition.
There is an important part of the conversation surrounding lexical and dynamic scoping that is missing: a plain explanation of the lifetime of the scoped variable - or when the variable can be accessed.
Dynamic scoping only very loosely corresponds to "global" scoping in the way that we traditionally think about it (the reason I bring up the comparison between the two is that it has already been mentioned - and I don't particularly like the linked article's explanation); it is probably best we don't make the comparison between global and dynamic - though supposedly, according to the linked article, "...[it] is useful as a substitute for globally scoped variables."
So, in plain English, what's the important distinction between the two scoping mechanisms?
Lexical scoping has been defined very well throughout the answers above: lexically scoped variables are available - or, accessible - at the local level of the function in which it was defined.
However - as it is not the focus of the OP - dynamic scoping has not received a great deal of attention and the attention it has received means it probably needs a bit more (that's not a criticism of other answers, but rather a "oh, that answer made we wish there was a bit more"). So, here's a little bit more:
Dynamic scoping means that a variable is accessible to the larger program during the lifetime of the function call - or, while the function is executing. Really, Wikipedia actually does a nice job with the explanation of the difference between the two. So as not to obfuscate it, here is the text that describes dynamic scoping:
...[I]n dynamic scoping (or dynamic scope), if a variable name's scope is a
certain function, then its scope is the time-period during which the
function is executing: while the function is running, the variable
name exists, and is bound to its variable, but after the function
returns, the variable name does not exist.
Ancient question, but here is my take on it.
Lexical (static) scope refers to the scope of a variable in the source code.
In a language like JavaScript, where functions can be passed around and attached and re-attached to miscellaneous objects, you might have though that scope would depend on who’s calling the function at the time, but it doesn’t. Changing the scope that way would be dynamic scope, and JavaScript doesn’t do that, except possibly with the this object reference.
To illustrate the point:
var a='apple';
function doit() {
var a='aardvark';
return function() {
alert(a);
}
}
var test=doit();
test();
In the example, the variable a is defined globally, but shadowed in the doit() function. This function returns another function which, as you see, relies on the a variable outside of its own scope.
If you run this, you will find that the value used is aardvark, not apple which, though it is in the scope of the test() function, is not in the lexical scope of the original function. That is, the scope used is the scope as it appears in the source code, not the scope where the function is actually used.
This fact can have annoying consequences. For example, you might decide that it’s easier to organise your functions separately, and then use them when the time comes, such as in an event handler:
var a='apple',b='banana';
function init() {
var a='aardvark',b='bandicoot';
document.querySelector('button#a').onclick=function(event) {
alert(a);
}
document.querySelector('button#b').onclick=doB;
}
function doB(event) {
alert(b);
}
init();
<button id="a">A</button>
<button id="b">B</button>
This code sample does one of each. You can see that because of lexical scoping, button A uses the inner variable, while button B doesn’t. You may end up nesting functions more than you would have liked.
By the way, in both examples, you will also notice that the inner lexically scoped variables persist even though the containing function function has run its course. This is called closure, and refers to a nested function’s access to outer variables, even if the outer function has finished. JavaScript needs to be smart enough to determine whether those variables are no longer needed, and if not, can garbage collect them.
Here's a different angle on this question that we can get by taking a step back and looking at the role of scoping in the larger framework of interpretation (running a program). In other words, imagine that you were building an interpreter (or compiler) for a language and were responsible for computing the output, given a program and some input to it.
Interpretation involves keeping track of three things:
State - namely, variables and referenced memory locations on the heap and stack.
Operations on that state - namely, every line of code in your program
The environment in which a given operation runs - namely, the projection of state on an operation.
An interpreter starts at the first line of code in a program, computes its environment, runs the line in that environment and captures its effect on the program's state. It then follows the program's control flow to execute the next line of code, and repeats the process till the program ends.
The way you compute the environment for any operation is through a formal set of rules defined by the programming language. The term "binding" is frequently used to describe the mapping of the overall state of the program to a value in the environment. Note that by "overall state" we do not mean global state, but rather the sum total of every reachable definition, at any point in the execution).
This is the framework in which the scoping problem is defined. Now to the next part of what our options are.
As the implementor of the interpreter, you could simplify your task by making the environment as close as possible to the program's state. Accordingly, the environment of a line of code would simply be defined by environment of the previous line of code with the effects of that operation applied to it, regardless of whether the previous line was an assignment, a function call, return from a function, or a control structure such as a while loop.
This is the gist of dynamic scoping, wherein the environment that any code runs in is bound to the state of the program as defined by its execution context.
Or, you could think of a programmer using your language and simplify his or her task of keeping track of the values a variable can take. There are way too many paths and too much complexity involved in reasoning about the outcome the totality of past execution. Lexical Scoping helps do this by restricting the current environment to the portion of state defined in the current block, function or other unit of scope, and its parent (i.e. the block enclosing the current clock, or the function that called the present function).
In other words, with lexical scope the environment that any code sees is bound to state associated with a scope defined explicitly in the language, such as a block or a function.
Scope is the context within which a variable/binding is accessible. Lexical scope means local to the enclosing lexical block or blocks as opposed to for instance global scope.
This topic is strongly related with the built-in bind function and introduced in ECMAScript 6 Arrow Functions. It was really annoying, because for every new "class" (function actually) method we wanted to use, we had to bind this in order to have access to the scope.
JavaScript by default doesn't set its scope of this on functions (it doesn't set the context on this). By default you have to explicitly say which context you want to have.
The arrow functions automatically gets so-called lexical scope (have access to variable's definition in its containing block). When using arrow functions it automatically binds this to the place where the arrow function was defined in the first place, and the context of this arrow functions is its containing block.
See how it works in practice on the simplest examples below.
Before Arrow Functions (no lexical scope by default):
const programming = {
language: "JavaScript",
getLanguage: function() {
return this.language;
}
}
const globalScope = programming.getLanguage;
console.log(globalScope()); // Output: undefined
const localScope = programming.getLanguage.bind(programming);
console.log(localScope()); // Output: "JavaScript"
With arrow functions (lexical scope by default):
const programming = {
language: "JavaScript",
getLanguage: function() {
return this.language;
}
}
const arrowFunction = () => {
console.log(programming.getLanguage());
}
arrowFunction(); // Output: "JavaScript"
Lexical scoping means functions resolve free variables from the scope where they were defined, not from the scope where they are called.
I normally learn by example, and here's a little something:
const lives = 0;
function catCircus () {
this.lives = 1;
const lives = 2;
const cat1 = {
lives: 5,
jumps: () => {
console.log(this.lives);
}
};
cat1.jumps(); // 1
console.log(cat1); // { lives: 5, jumps: [Function: jumps] }
const cat2 = {
lives: 5,
jumps: () => {
console.log(lives);
}
};
cat2.jumps(); // 2
console.log(cat2); // { lives: 5, jumps: [Function: jumps] }
const cat3 = {
lives: 5,
jumps: () => {
const lives = 3;
console.log(lives);
}
};
cat3.jumps(); // 3
console.log(cat3); // { lives: 5, jumps: [Function: jumps] }
const cat4 = {
lives: 5,
jumps: function () {
console.log(lives);
}
};
cat4.jumps(); // 2
console.log(cat4); // { lives: 5, jumps: [Function: jumps] }
const cat5 = {
lives: 5,
jumps: function () {
var lives = 4;
console.log(lives);
}
};
cat5.jumps(); // 4
console.log(cat5); // { lives: 5, jumps: [Function: jumps] }
const cat6 = {
lives: 5,
jumps: function () {
console.log(this.lives);
}
};
cat6.jumps(); // 5
console.log(cat6); // { lives: 5, jumps: [Function: jumps] }
const cat7 = {
lives: 5,
jumps: function thrownOutOfWindow () {
console.log(this.lives);
}
};
cat7.jumps(); // 5
console.log(cat7); // { lives: 5, jumps: [Function: thrownOutOfWindow] }
}
catCircus();
Related
Does top level functions makes closure in JavaScript?
I am learning closure and have basic doubt. function makeCounter() { let count = 0; return function() { return count++; }; } let counter = makeCounter(); Here when we are returning function it has closure with outer scope. so it has a closure with count. var x = 1; function func() { console.log(x); // does func has closure with x ?? } func(); So my question is , only nested function makes closure ?? or top level func has also closure with x ??
Closures in JavaScript are implemented using the [[OuterEnv]] internal field of the [[EnvironmentRecord]] internal field of function declarations. The [[OuterEnv]] value is then copied to the execution context created any time a function is called. This value is then used to create the scope chain, enabling the closure behavior. Functions declared in the global context are no different in this regard and maintain a link to their surrounding environment, the Global Environment Record. In the global context, variables declared using var and function declarations behave subtly differently to those declared inside other functions, in that they end up as properties on the global object, but this is an implementation detail.
For the sake of conversation, lets say that every closure creates a "scope" where variables are defined - everything within the closure/scope can access variables, anything outside cannot. With that said, there are two different types of implied closures you should be aware of. This is not an exhastive description of how closures work, but more of description of the basic practical concepts as they relate to this question. There is much more going on with how call stacks are created, lexical scoping, "global" scope within NodeJS, iframes, sandboxing, var vs const/let, block vs function scopes, and other concepts which I will leave to the reader to discover on their own. The browser/window/global scope In the browser, you have the top-level scope (basically window, often referred to as the "global" scope). This kind of acts as a closure in that all "non-enclosed" variables are defined as part of the window scope and are available to most other code running on that page. For example, if you include the following script in the browser, x is part of the global/window scope, whereas y and z are enclosed inside their own nested scopes. // basic-script.js // x becomes part of the global/window scope const x = 10; (() => { // y is enclosed in a separate, nested closure const y = 20; // x is available in this nested scope/closure console.log('The sum of x and y is', x + y); function foo() { // z is enclosed in a separate, nested closure const z = 5; // x and y are both available in this nested scope/closure console.log('The sum of x y and z is', x + y + z); } foo(); // z is not available to the parent scope console.log(z); //-> undefined })(); // y is not available to the parent scope console.log(y); //-> undefined <script src="basic-script.js"></script> <script> // this works because x is not enclosed console.log('The value of x is', x); // y and z are not available as they are inside a separate closure console.log(y, z); //-> undefined, undefined </script> JavaScript modules When you write JavaScript which is imported or required by other modules, every module is automatically wrapped in its own closure. For example, if you were to import/require the above basic-script.js into another JavaScript file, the above would be automatically enclosed like this: (function() { var x = 10; // ... other code removed for brevity })(); There is some other magic going on for exposing exports and so forth, but that's beyond the scope of this answer (pun intended). If JS modules were not wrapped in their own closure, then you would have a mess of naming collisions and reference issues, as well as a security nightmare. So to answer your question, yes - your second example shares a closure with "x" - the closure is implicitly created depending on your environment.
Don't know, if you are still searching for the answer or not. What is you meant by top level, I think you are talking about the global scope. To understand closure one should understand scope better. And No, Closure in not work in global scope. The main reason of closure is to create a function that return a function with specific variables/calculations with it so that you can reuse that value again. I have a detailed blog in scope, closure and lexical environment. You can check it out https://shimulhsn.hashnode.dev/lexical-environment-and-scope-chain
A practical use of closures is creating a "scope" of protection around variables and functions declared within that function from outside interference. The top scope is "global", accessed using the window variable (an object). Everything, regardless what scope it was declared in, has access to it. A function declared in global scope creates its own scope that no expression in the global scope and other "sub-global" scopes has access to. Functions declared in the global scope or declared inside other functions create their own scope, that even its immediate parent scope doesn't have access to. Any variable declared—var, let, const—inside a function block is accessible in that function scope and any sub-scope created within that function scope—i.e., nothing outside that function scope can access it, (except a mechanism the function creating the scope may provide). The second example in the question, where x is declared in the global scope, means everything has access to x. If x is later changed it is changed in all scopes. x is wide-open to interference anywhere in the code. var x = 1; <-- declared outside func() function func() { // ...etc., etc., etc. In the first example: function makeCounter() { let count = 0; return function() { return count++; }; } ...makeCounter() creates a scope that includes count and an anonymous function, and that has access to them. Sub-scopes within this scope also have access to them. However, any expression in the global scope or other sub-global scopes do not have access to them. Regarding the description that closures give access to an outer function's scope from an inner function—that scope access travels "up", accessing every parent scope, all the way to global scope, regardless how far "down" the "scope-chain" it goes. For example: const can_i_reach_global = 'yes'; topLevel(); function topLevel () { console.log('topLevel func, can_i_reach_global:', can_i_reach_global); oneDeep(); function oneDeep () { console.log('oneDeep func, can_i_reach_global:', can_i_reach_global); twoDeep(); function twoDeep () { console.log('twoDeep func, can_i_reach_global:', can_i_reach_global) } } } So, as far as practical definitions go, simply stating function closure "...gives you access to an outer function's scope from an inner function..." doesn't describe the usefulness of this programming construct.
Does this function have closure over this block?
I am experimenting with closures but rather than enclosing a function within a function, I enclosed a function within a block. Since functions are not blocked-scoped and will be hoisted outside of the block I assumed that it wouldn't have access to the scope within the block. Yet, in this case, the function returns the block-scoped variable. Does this mean that the function is a closure? { let a = 'hi' function test() { return a } } test() // hi
I'd be happy to call it a closure, at least according to Wikpedia's definition: Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope. In your function test, the variable a is a free variable, used by the function but not defined inside the function. When you called the function outside the block, it retained the value of a. So, you've met the essential points of the definition of closure (according to Wikipedia). Of course, you asked the question because it's kind of tricky. Normally with closures, we define a function inside an environment and then "export" it out by binding the function object to a name that has a wider scope. Because of the way JavaScript treats function declarations defined in a block (see Code Maniac's link to the ECMAScript specification on handling block-scoped function declarations) you do get this effect! So it's kind of a closure, even though you never explicitly exported the function. Of course if you had written { let a = 'hi' let test = () => a } test() you get an error. But this works: let b; { let a = 'hi' let test = () => a b = test } b() // "hi" so yes, the block is acting as the non-local environment from which variables can be captured. I'm thinking yes, it's okay to speak of this as being a closure, because it acts like one (even if this behavior comes from a pre-ECMAScript 2015, "optional", and non-strict treatment of function declarations inside of blocks). If it walks like a duck, and all that.
Reassigning let variables [duplicate]
What is a brief introduction to lexical scoping?
I understand them through examples. :) First, lexical scope (also called static scope), in C-like syntax: void fun() { int x = 5; void fun2() { printf("%d", x); } } Every inner level can access its outer levels. There is another way, called dynamic scope used by the first implementation of Lisp, again in a C-like syntax: void fun() { printf("%d", x); } void dummy1() { int x = 5; fun(); } void dummy2() { int x = 10; fun(); } Here fun can either access x in dummy1 or dummy2, or any x in any function that call fun with x declared in it. dummy1(); will print 5, dummy2(); will print 10. The first one is called static because it can be deduced at compile-time, and the second is called dynamic because the outer scope is dynamic and depends on the chain call of the functions. I find static scoping easier for the eye. Most languages went this way eventually, even Lisp (can do both, right?). Dynamic scoping is like passing references of all variables to the called function. As an example of why the compiler can not deduce the outer dynamic scope of a function, consider our last example. If we write something like this: if(/* some condition */) dummy1(); else dummy2(); The call chain depends on a run time condition. If it is true, then the call chain looks like: dummy1 --> fun() If the condition is false: dummy2 --> fun() The outer scope of fun in both cases is the caller plus the caller of the caller and so on. Just to mention that the C language does not allow nested functions nor dynamic scoping.
Lets try the shortest possible definition: Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned. That is all there is to it!
var scope = "I am global"; function whatismyscope(){ var scope = "I am just a local"; function func() {return scope;} return func; } whatismyscope()() The above code will return "I am just a local". It will not return "I am a global". Because the function func() counts where is was originally defined which is under the scope of function whatismyscope. It will not bother from whatever it is being called(the global scope/from within another function even), that's why global scope value I am global will not be printed. This is called lexical scoping where "functions are executed using the scope chain that was in effect when they were defined" - according to JavaScript Definition Guide. Lexical scope is a very very powerful concept.
Lexical (AKA static) scoping refers to determining a variable's scope based solely on its position within the textual corpus of code. A variable always refers to its top-level environment. It's good to understand it in relation to dynamic scope.
Scope defines the area, where functions, variables and such are available. The availability of a variable for example is defined within its the context, let's say the function, file, or object, they are defined in. We usually call these local variables. The lexical part means that you can derive the scope from reading the source code. Lexical scope is also known as static scope. Dynamic scope defines global variables that can be called or referenced from anywhere after being defined. Sometimes they are called global variables, even though global variables in most programmin languages are of lexical scope. This means, it can be derived from reading the code that the variable is available in this context. Maybe one has to follow a uses or includes clause to find the instatiation or definition, but the code/compiler knows about the variable in this place. In dynamic scoping, by contrast, you search in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call stack. "Dynamic" refers to change, in that the call stack can be different every time a given function is called, and so the function might hit different variables depending on where it is called from. (see here) To see an interesting example for dynamic scope see here. For further details see here and here. Some examples in Delphi/Object Pascal Delphi has lexical scope. unit Main; uses aUnit; // makes available all variables in interface section of aUnit interface var aGlobal: string; // global in the scope of all units that use Main; type TmyClass = class strict private aPrivateVar: Integer; // only known by objects of this class type // lexical: within class definition, // reserved word private public aPublicVar: double; // known to everyboday that has access to a // object of this class type end; implementation var aLocalGlobal: string; // known to all functions following // the definition in this unit end. The closest Delphi gets to dynamic scope is the RegisterClass()/GetClass() function pair. For its use see here. Let's say that the time RegisterClass([TmyClass]) is called to register a certain class cannot be predicted by reading the code (it gets called in a button click method called by the user), code calling GetClass('TmyClass') will get a result or not. The call to RegisterClass() does not have to be in the lexical scope of the unit using GetClass(); Another possibility for dynamic scope are anonymous methods (closures) in Delphi 2009, as they know the variables of their calling function. It does not follow the calling path from there recursively and therefore is not fully dynamic.
A lexical scope in JavaScript means that a variable defined outside a function can be accessible inside another function defined after the variable declaration. But the opposite is not true; the variables defined inside a function will not be accessible outside that function. This concept is heavily used in closures in JavaScript. Let's say we have the below code. var x = 2; var add = function() { var y = 1; return x + y; }; Now, when you call add() --> this will print 3. So, the add() function is accessing the global variable x which is defined before method function add. This is called due to lexical scoping in JavaScript.
Lexical scope means that in a nested group of functions, the inner functions have access to the variables and other resources of their parent scope. This means that the child's functions are lexically bound to the execution context of their parents. Lexical scope is sometimes also referred to as static scope. function grandfather() { var name = 'Hammad'; // 'likes' is not accessible here function parent() { // 'name' is accessible here // 'likes' is not accessible here function child() { // Innermost level of the scope chain // 'name' is also accessible here var likes = 'Coding'; } } } The thing you will notice about lexical scope is that it works forward, meaning the name can be accessed by its children's execution contexts. But it doesn't work backward to its parents, meaning that the variable likes cannot be accessed by its parents. This also tells us that variables having the same name in different execution contexts gain precedence from top to bottom of the execution stack. A variable, having a name similar to another variable, in the innermost function (topmost context of the execution stack) will have higher precedence. Source.
I love the fully featured, language-agnostic answers from folks like #Arak. Since this question was tagged JavaScript though, I'd like to chip in some notes very specific to this language. In JavaScript our choices for scoping are: as-is (no scope adjustment) lexical var _this = this; function callback(){ console.log(_this); } bound callback.bind(this) It's worth noting, I think, that JavaScript doesn't really have dynamic scoping. .bind adjusts the this keyword, and that's close, but not technically the same. Here is an example demonstrating both approaches. You do this every time you make a decision about how to scope callbacks so this applies to promises, event handlers, and more. Lexical Here is what you might term Lexical Scoping of callbacks in JavaScript: var downloadManager = { initialize: function() { var _this = this; // Set up `_this` for lexical access $('.downloadLink').on('click', function () { _this.startDownload(); }); }, startDownload: function(){ this.thinking = true; // Request the file from the server and bind more callbacks for when it returns success or failure } //... }; Bound Another way to scope is to use Function.prototype.bind: var downloadManager = { initialize: function() { $('.downloadLink').on('click', function () { this.startDownload(); }.bind(this)); // Create a function object bound to `this` } //... These methods are, as far as I know, behaviorally equivalent.
In simple language, lexical scope is a variable defined outside your scope or upper scope is automatically available inside your scope which means you don't need to pass it there. Example: let str="JavaScript"; const myFun = () => { console.log(str); } myFun(); // Output: JavaScript
Lexical scope means that a function looks up variables in the context where it was defined, and not in the scope immediately around it. Look at how lexical scope works in Lisp if you want more detail. The selected answer by Kyle Cronin in Dynamic and Lexical variables in Common Lisp is a lot clearer than the answers here. Coincidentally I only learned about this in a Lisp class, and it happens to apply in JavaScript as well. I ran this code in Chrome's console. // JavaScript Equivalent Lisp var x = 5; //(setf x 5) console.debug(x); //(print x) function print_x(){ //(defun print-x () console.debug(x); // (print x) } //) (function(){ //(let var x = 10; // ((x 10)) console.debug(x); // (print x) print_x(); // (print-x) })(); //) Output: 5 10 5
Lexical scoping: Variables declared outside of a function are global variables and are visible everywhere in a JavaScript program. Variables declared inside a function have function scope and are visible only to code that appears inside that function.
IBM defines it as: The portion of a program or segment unit in which a declaration applies. An identifier declared in a routine is known within that routine and within all nested routines. If a nested routine declares an item with the same name, the outer item is not available in the nested routine. Example 1: function x() { /* Variable 'a' is only available to function 'x' and function 'y'. In other words the area defined by 'x' is the lexical scope of variable 'a' */ var a = "I am a"; function y() { console.log( a ) } y(); } // outputs 'I am a' x(); Example 2: function x() { var a = "I am a"; function y() { /* If a nested routine declares an item with the same name, the outer item is not available in the nested routine. */ var a = 'I am inner a'; console.log( a ) } y(); } // outputs 'I am inner a' x();
I hope this is helpful, here is my attempt at a slightly more abstract definition: Lexical scope: The access or range something (e.g. a function or variable) has to other elements in the program as determined by its position in the source code. Fwiw, my logic here simply builds from the definitions of: Lexical: relating to the words or vocabulary of a language (specifically the word as separate from it's grammar or construction) {in our case - a programming language}. Scope (noun): the range of operation {in our case the range is: what can be accessed}. Note, the original 1960 definition of Lexical Scope from the ALGOL 60 spec is far more pithy than my attempt above: Lexical scope: the portion of source code in which a binding of a name with an entity applies. source
Lexical scope refers to the lexicon of identifiers (e.g., variables, functions, etc.) visible from the current position in the execution stack. - global execution context - foo - bar - function1 execution context - foo2 - bar2 - function2 execution context - foo3 - bar3 foo and bar are always within the lexicon of available identifiers because they are global. When function1 is executed, it has access to a lexicon of foo2, bar2, foo, and bar. When function2 is executed, it has access to a lexicon of foo3, bar3, foo2, bar2, foo, and bar. The reason global and/or outer functions do not have access to an inner functions identifiers is because the execution of that function has not occurred yet and therefore, none of its identifiers have been allocated to memory. What’s more, once that inner context executes, it is removed from the execution stack, meaning that all of it’s identifiers have been garbage collected and are no longer available. Finally, this is why a nested execution context can ALWAYS access it’s ancestors execution context and thus why it has access to a greater lexicon of identifiers. See: https://tylermcginnis.com/ultimate-guide-to-execution-contexts-hoisting-scopes-and-closures-in-javascript/ https://developer.mozilla.org/en-US/docs/Glossary/Identifier Special thanks to #robr3rd for help simplifying the above definition.
There is an important part of the conversation surrounding lexical and dynamic scoping that is missing: a plain explanation of the lifetime of the scoped variable - or when the variable can be accessed. Dynamic scoping only very loosely corresponds to "global" scoping in the way that we traditionally think about it (the reason I bring up the comparison between the two is that it has already been mentioned - and I don't particularly like the linked article's explanation); it is probably best we don't make the comparison between global and dynamic - though supposedly, according to the linked article, "...[it] is useful as a substitute for globally scoped variables." So, in plain English, what's the important distinction between the two scoping mechanisms? Lexical scoping has been defined very well throughout the answers above: lexically scoped variables are available - or, accessible - at the local level of the function in which it was defined. However - as it is not the focus of the OP - dynamic scoping has not received a great deal of attention and the attention it has received means it probably needs a bit more (that's not a criticism of other answers, but rather a "oh, that answer made we wish there was a bit more"). So, here's a little bit more: Dynamic scoping means that a variable is accessible to the larger program during the lifetime of the function call - or, while the function is executing. Really, Wikipedia actually does a nice job with the explanation of the difference between the two. So as not to obfuscate it, here is the text that describes dynamic scoping: ...[I]n dynamic scoping (or dynamic scope), if a variable name's scope is a certain function, then its scope is the time-period during which the function is executing: while the function is running, the variable name exists, and is bound to its variable, but after the function returns, the variable name does not exist.
Ancient question, but here is my take on it. Lexical (static) scope refers to the scope of a variable in the source code. In a language like JavaScript, where functions can be passed around and attached and re-attached to miscellaneous objects, you might have though that scope would depend on who’s calling the function at the time, but it doesn’t. Changing the scope that way would be dynamic scope, and JavaScript doesn’t do that, except possibly with the this object reference. To illustrate the point: var a='apple'; function doit() { var a='aardvark'; return function() { alert(a); } } var test=doit(); test(); In the example, the variable a is defined globally, but shadowed in the doit() function. This function returns another function which, as you see, relies on the a variable outside of its own scope. If you run this, you will find that the value used is aardvark, not apple which, though it is in the scope of the test() function, is not in the lexical scope of the original function. That is, the scope used is the scope as it appears in the source code, not the scope where the function is actually used. This fact can have annoying consequences. For example, you might decide that it’s easier to organise your functions separately, and then use them when the time comes, such as in an event handler: var a='apple',b='banana'; function init() { var a='aardvark',b='bandicoot'; document.querySelector('button#a').onclick=function(event) { alert(a); } document.querySelector('button#b').onclick=doB; } function doB(event) { alert(b); } init(); <button id="a">A</button> <button id="b">B</button> This code sample does one of each. You can see that because of lexical scoping, button A uses the inner variable, while button B doesn’t. You may end up nesting functions more than you would have liked. By the way, in both examples, you will also notice that the inner lexically scoped variables persist even though the containing function function has run its course. This is called closure, and refers to a nested function’s access to outer variables, even if the outer function has finished. JavaScript needs to be smart enough to determine whether those variables are no longer needed, and if not, can garbage collect them.
Here's a different angle on this question that we can get by taking a step back and looking at the role of scoping in the larger framework of interpretation (running a program). In other words, imagine that you were building an interpreter (or compiler) for a language and were responsible for computing the output, given a program and some input to it. Interpretation involves keeping track of three things: State - namely, variables and referenced memory locations on the heap and stack. Operations on that state - namely, every line of code in your program The environment in which a given operation runs - namely, the projection of state on an operation. An interpreter starts at the first line of code in a program, computes its environment, runs the line in that environment and captures its effect on the program's state. It then follows the program's control flow to execute the next line of code, and repeats the process till the program ends. The way you compute the environment for any operation is through a formal set of rules defined by the programming language. The term "binding" is frequently used to describe the mapping of the overall state of the program to a value in the environment. Note that by "overall state" we do not mean global state, but rather the sum total of every reachable definition, at any point in the execution). This is the framework in which the scoping problem is defined. Now to the next part of what our options are. As the implementor of the interpreter, you could simplify your task by making the environment as close as possible to the program's state. Accordingly, the environment of a line of code would simply be defined by environment of the previous line of code with the effects of that operation applied to it, regardless of whether the previous line was an assignment, a function call, return from a function, or a control structure such as a while loop. This is the gist of dynamic scoping, wherein the environment that any code runs in is bound to the state of the program as defined by its execution context. Or, you could think of a programmer using your language and simplify his or her task of keeping track of the values a variable can take. There are way too many paths and too much complexity involved in reasoning about the outcome the totality of past execution. Lexical Scoping helps do this by restricting the current environment to the portion of state defined in the current block, function or other unit of scope, and its parent (i.e. the block enclosing the current clock, or the function that called the present function). In other words, with lexical scope the environment that any code sees is bound to state associated with a scope defined explicitly in the language, such as a block or a function.
Scope is the context within which a variable/binding is accessible. Lexical scope means local to the enclosing lexical block or blocks as opposed to for instance global scope.
This topic is strongly related with the built-in bind function and introduced in ECMAScript 6 Arrow Functions. It was really annoying, because for every new "class" (function actually) method we wanted to use, we had to bind this in order to have access to the scope. JavaScript by default doesn't set its scope of this on functions (it doesn't set the context on this). By default you have to explicitly say which context you want to have. The arrow functions automatically gets so-called lexical scope (have access to variable's definition in its containing block). When using arrow functions it automatically binds this to the place where the arrow function was defined in the first place, and the context of this arrow functions is its containing block. See how it works in practice on the simplest examples below. Before Arrow Functions (no lexical scope by default): const programming = { language: "JavaScript", getLanguage: function() { return this.language; } } const globalScope = programming.getLanguage; console.log(globalScope()); // Output: undefined const localScope = programming.getLanguage.bind(programming); console.log(localScope()); // Output: "JavaScript" With arrow functions (lexical scope by default): const programming = { language: "JavaScript", getLanguage: function() { return this.language; } } const arrowFunction = () => { console.log(programming.getLanguage()); } arrowFunction(); // Output: "JavaScript"
Lexical scoping means functions resolve free variables from the scope where they were defined, not from the scope where they are called.
I normally learn by example, and here's a little something: const lives = 0; function catCircus () { this.lives = 1; const lives = 2; const cat1 = { lives: 5, jumps: () => { console.log(this.lives); } }; cat1.jumps(); // 1 console.log(cat1); // { lives: 5, jumps: [Function: jumps] } const cat2 = { lives: 5, jumps: () => { console.log(lives); } }; cat2.jumps(); // 2 console.log(cat2); // { lives: 5, jumps: [Function: jumps] } const cat3 = { lives: 5, jumps: () => { const lives = 3; console.log(lives); } }; cat3.jumps(); // 3 console.log(cat3); // { lives: 5, jumps: [Function: jumps] } const cat4 = { lives: 5, jumps: function () { console.log(lives); } }; cat4.jumps(); // 2 console.log(cat4); // { lives: 5, jumps: [Function: jumps] } const cat5 = { lives: 5, jumps: function () { var lives = 4; console.log(lives); } }; cat5.jumps(); // 4 console.log(cat5); // { lives: 5, jumps: [Function: jumps] } const cat6 = { lives: 5, jumps: function () { console.log(this.lives); } }; cat6.jumps(); // 5 console.log(cat6); // { lives: 5, jumps: [Function: jumps] } const cat7 = { lives: 5, jumps: function thrownOutOfWindow () { console.log(this.lives); } }; cat7.jumps(); // 5 console.log(cat7); // { lives: 5, jumps: [Function: thrownOutOfWindow] } } catCircus();
Is a function return necessary to be called a Closure
Hey i came across this video on youtube http://www.youtube.com/watch?v=KRm-h6vcpxs which basically explains IIFEs and closures. But what I am not understanding is whether i need to return a function in order to call it a closure. E.x. function a() { var i = 10; function b() { alert(i); } } in this case can i call it a closure as it is accessing the 'i' variable from the outer function's scope or do i need to return the function like this return function b(){alert(i);}
A closure is simply a function which holds its lexical environment and doesn't let it go until it itself dies. Think of a closure as Uncle Scrooge: Uncle Scrooge is a miser. He will never let go of his money. Similarly a closure is also a miser. It will not let go of its variables until it dies itself. For example: function getCounter() { var count = 0; return function counter() { return ++count; }; } var counter = getCounter(); See that function counter? The one returned by the getCounter function? That function is a miser. It will not let go of the count variable even though the count variable belongs to the getCounter function call and that function call has ended. Hence we call counter a closure. See every function call may create variables. For example a call to the getCounter function creates a variable count. Now this variable count usually dies when the getCounter function ends. However the counter function (which can access the count variable) doesn't allow it to die when the call to getCounter ends. This is because the counter function needs count. Hence it will only allow count to die after it dies itself. Now the really interesting thing to notice here is that counter is born inside the call to getCounter. Hence even counter should die when the call to getCounter ends - but it doesn't. It lives on even after the call to getCounter ends because it escapes the scope (lifetime) of getCounter. There are many ways in which counter can escape the scope of getCounter. The most common way is for getCounter to simply return counter. However there are many more ways. For example: var counter; function setCounter() { var count = 0; counter = function counter() { return ++count; }; } setCounter(); Here the sister function of getCounter (which is aptly called setCounter) assigns a new counter function to the global counter variable. Hence the inner counter function escapes the scope of setCounter to become a closure. Actually in JavaScript every function is a closure. However we don't realize this until we deal with functions which escape the scope of a parent function and keep some variable belonging to the parent function alive even after the call to the parent function ends. For more information read this answer: https://stackoverflow.com/a/12931785/783743
Returning the function changes nothing, what's important is creating it and calling it. That makes the closure, that is a link from the internal function to the scope where it was created (you can see it, in practice, as a pointer. It has the same effect of preventing the garbaging of the outer scope, for example).
By definition of closure, the link from the function to its containing scope is enough. So basically creating the function makes it a closure, since that is where the link is created in JavaScript :-) Yet, for utilizing this feature we do call the function from a different scope than what it was defined in - that's what the term "use a closure" in practise refers to. This can both be a lower or a higher scope - and the function does not necessarily need to be returned from the function where it was defined in. Some examples: var x = null; function a() { var i = "from a"; function b() { alert(i); // reference to variable from a's scope } function c() { var i = "c"; // use from lower scope b(); // "from a" - not "c" } c(); // export by argument passing [0].forEach(b); // "from a"; // export by assigning to variable in higher scope x = b; // export by returning return b; } var y = a(); x(); // "from a" y(); // "from a"
The actual closure is a container for variables, so that a function can use variables from the scope where it is created. Returning a function is one way of using it in a different scope from where it is created, but a more common use is when it's a callback from an asynchronous call. Any situation where a function uses variables from one scope, and the function is used in a different scope uses a closure. Example: var globalF; // a global variable function x() { // just to have a local scope var local; // a local variable in the scope var f = function(){ alert(local); // use the variable from the scope }; globalF = f; // copy a reference to the function to the global variable } x(); // create the function globalF(); // call the function (This is only a demonstration of a closure, having a function set a global variable which is then used is not a good way to write actual code.)
a collection of explanations of closure below. to me, the one from "tiger book" satisfies me most...metaphoric ones also help a lot, but only after encounterred this one... closure: in set theory, a closure is a (smallest) set, on which some operations yields results also belongs to the set, so it's sort of "smallest closed society under certain operations". a) sicp: in abstract algebra, where a set of elements is said to be closed under an operation if applying the operation to elements in the set produces an element that is again an element of the set. The Lisp community also (unfortunately) uses the word "closure" to describe a totally unrelated concept: a closure is an implementation technique for representing procedures with free variables. b) wiki: a closure is a first class function which captures the lexical bindings of free variables in its defining environment. Once it has captured the lexical bindings the function becomes a closure because it "closes over" those variables.” c) tiger book: a data structure on heap (instead of on stack) that contains both function pointer (MC) and environment pointer (EP), representing a function variable; d) on lisp: a combination of a function and a set of variable bindings is called a closure; closures are functions with local state; e) google i/o video: similar to a instance of a class, in which the data (instance obj) encapsulates code (vtab), where in case of closure, the code (function variable) encapsulates data. f) the encapsulated data is private to the function variable, implying closure can be used for data hiding. g) closure in non-functional programming languages: callback with cookie in C is a similar construct, also the glib "closure": a glib closure is a data structure encapsulating similar things: a signal callback pointer, a cookie the private data, and a destructor of the closure (as there is no GC in C). h) tiger book: "higher-order function" and "nested function scope" together require a solution to the case that a dad function returns a kid function which refers to variables in the scope of its dad implying that even dad returns the variables in its scope cannot be "popup" from the stack...the solution is to allocate closures in heap. i) Greg Michaelson ($10.15): (in lisp implementation), closure is a way to identify the relationship betw free variables and lexical bound variables, when it's necessary (as often needed) to return a function value with free variables frozen to values from the defining scope. j) histroy and etymology: Peter J. Landin defined the term closure in 1964 as having an environment part and a control part as used by his SECD machine for evaluating expressions. Joel Moses credits Landin with introducing the term closure to refer to a lambda expression whose open bindings (free variables) have been closed by (or bound in) the lexical environment, resulting in a closed expression, or closure. This usage was subsequently adopted by Sussman and Steele when they defined Scheme in 1975, and became widespread.
javascript closure advantages?
Whats the main purpose of Closures in JS. Is it just used for public and private variables? or is there something else that I missed. I am trying to understand closure and really want to know what are the main advantages of using it.
Closures have to do with how javascript is scoped. To say it another way, because of the scoping choices (i.e. lexical scoping) the javascript designers made, closures are possible. The advantage of closures in javascript is that it allows you to bind a variable to an execution context. var closedIn = {}; var f = function(){ closedIn.blah = 'blah'; // closedIn was just "closed in" because I used in the function, but it was defined outside the function. } in that example, you have a normal object literal called closedIn. It is accessed in a function. Because of that, javascript knows it has to bring closedIn everywhere it brings the function f, so it is available to f. The this keyword is tricky. this is always a reference to the execution scope. You can capture the this of one context to use in another context as follows: var that = this; var f = function(){ that.somethingOnThat(); // `this` means the scope f, `that` means whatever 'this' was when defined outside of the function } This trick can be very useful somethings, if you are coding object oriented javascript and want a callback to have access to some external scope. To quote from a Javascript book: "Functions in JavaScript are lexically rather than dynamically scoped. This means that they run in the scope in which they are defined, not the scopee from which they are executed. When a function is defined, the current scope chain is saved and becomes part of the internal state of the function." So the clear advantage is that you can bring any object (functions, objects, etc) along with the scope chain as far as is necessary. This is can also be considered a risk, because your apps can easily consume lots of memory if you are not careful.
I think the best phrase to sum up the purpose of closures would be: Data Encapsulation With a function closure you can store data in a separate scope, and share it only where necessary. If you wanted to emulate private static variables, you could define a class inside a function, and define the private static vars within the closure: (function () { var foo; foo = 0; function MyClass() { foo += 1; } MyClass.prototype = { howMany: function () { return foo; } }; window.MyClass = MyClass; }());
Closures are necessary in javascript due to the fact that most API's that require callback functions (for instance, an "onclick" function) do not provide other mechanisms to send parameters to those callback functions (or to explicitly set the "this" pointer). Instead, you need to use closures to allow the callback to access variables in the "parent" function. I personally wish that they weren't necessary, since they can be hard to understand, make for hard to read code (it's not always clear what exactly is in scope), and make for weird bugs. Instead I wish there was a standard for callbacks that allowed you to send parameters, etc. But I accept that I am in the minority in this view.
As we know, the variables that are defined in functions, have local scope. We can't access them from outside of the function. Problem 1: local variables are created when the function is called and they will be destroyed when the function's task is finished. It means local variables have shorter life time than global variables. We may use global variables to overcome that issue. Global variables are available when the program starts and are destroyed when it ends. They are also available throughout the program. Problem 2: Since global variables are accessible throughout the program, they are prone to change from everywhere. What do we want? We want to have data persistency + data encapsulation. We can achieve them by using Closures. By using a closure we can have private variables that are available even after a function's task is finished. Example: function initCounter() { let counter = 0; return function () { return ++counter; } } // Each counter is persistent const countJumps = initCounter(); countJumps(); countJumps(); alert("Jumps count is: " + countJumps()); const countClicks = initCounter(); countClicks(); countClicks(); countClicks(); countClicks(); alert("Clicks count is: " + countClicks()); // Each counter is isolated alert(counter); // Error: counter is not defined