I have a for loop where I get the start number for my countdown. I want to use that number outside the for loop and here comes the closure problem.
for (var i = 0; i < response.length; i++) {
var number = response[i].number; //the number is 10
getNumber(number);
};
So I thought I should call a function that returns that number so I can use it somewhere else:
function getNumber(number) {
return number;
}
But when I try to do this, I get an undefined instead of 10:
var globalVariableForNumber = getNumber();
What I know I am doing wrong is calling getNumber() without the parameter when assigning the value to my variable, but how else should I do it?
The number comes from an ajax call that has more numbers in it (response[i].number). I then want to use those numbers to be the start timers of my countdown. So if the number is 10, then my countdown will start from 10.
Thank you.
var response = [
{number:5},
{number:6},
{number:7},
{number:8},
{number:9},
{number:10}
]
var number;
for (var i = 0; i < response.length; i++) {
number = response[i].number; //the number is 10
console.log(getNumber());
};
function getNumber() {
return number;
}
// try it again later...
console.log(getNumber());
Again, you should just be calling number directly. But for the purpose of this question you have to declare number in a higher scope.
Scope
The current context of execution. The context in which values and
expressions are "visible," or can be referenced. If a variable or
other expression is not "in the current scope," then it is unavailable
for use. Scopes can also be layered in a hierarchy, so that child
scopes have access to parent scopes, but not vice versa.
A function serves as a closure in JavaScript, and thus creates a
scope, so that (for example) a variable defined exclusively within the
function cannot be accessed from outside the function or within other
functions.
Consider this example of scopes that your code could be declared and called:
function ImInGlobalScope(){ //Function declared in global scope
//Lets call this block 1
for (var i = 0; i < response.length; i++) {
var number = response[i].number; //Inside function scope
getNumber(number)
};
//Lets call this block 2
function getNumber(number){ //In same scope than for statement
return number; //block 3
}
}
var globalVariableForNumber = getNumber();
With this example getNumber is undefined because it belongs to ImInGlobalScope() scope. Consider another scenario of scopes for your code.
function ImInGlobalScope(){ //Function declared in global scope
//Lets call this block 1
for (var i = 0; i < response.length; i++) {
var number = response[i].number; //Inside function scope
getNumber(number)
};
}
//Lets call this block 2
function getNumber(number){ //In same scope than for statement
return number; //block 3
}
var globalVariableForNumber = getNumber();
I believe the above is what your scenario is: getNumber is on global scope but number is ImInGlobalScope().
So when you're calling var globalVariableForNumber = getNumber(); We have the following:
function getNumber(number){ //Number is not being passed so is undefined
return number; //no variable named number exists in this scope so it will return undefined.
}
What you are doing is creating a function that takes exactly one parameter and returns that parameter when it is called. Return is a fancy way of saying that if you say foo=bar() then foo is whatever bar() returned.
In your code, calling getNumber() with no parameter returns undefined because it just returns the parameter. What you should do instead is not return the parameter, but instead set the global variable to it like so:
function getNumber(number) {
globalVariableForNumber = number;
}
Now, just get the number by running:
globalVariableForNumber
Related
I am trying to get around understanding javascript closures from a practical scenario.I know from a theoretical perspective , With the help of closures inner functions can have access to the variables in the enclosing function i.e parent function.
I have read a couple of questions on stackOverflow as well.
i am really missing the point of what is happening here?
var foo = [];
for(var i=0;i<10;i++){
foo[i] = function(){
return i;
}
}
console.log(foo[0]());
This gives me out a 10. Most of the articles say that by the time it reaches the inner anonymous function, The for loop is getting executed as a result the last value that is present in the loop which is 10 is being printed.
But i am still not able to get to the bottom of this.
On Contrary, If i use something like:
var foo = [];
for(var i=0;i<10;i++){
(function(){
var y =i;
foo[i] = function(){
return y;
}
})();
}
console.log(foo[0]());
I am getting the output.Any help would be highly appreciated.
maybe this code block helps
var foo = [];
for(var i = 0; i < 10; i++) {
foo[i] = function() {
return i; // is a reference and will always be the value, which 'i' have on function execution
}
}
// 'i' is 10 here!
console.log(foo[0]()); // executing the function will return the current value of 'i'
///////////////////////////////////////
var foo = [];
for(var i=0;i<10;i++) {
/* thats a IIFE (immediately invoked function expression) */
(function(a) { // 'a' is now a local variable
foo[a] = function() { // defines a function
return a; // is a reference to local variable 'a'
};
})(i); // <- passing the current value of i as parameter to the invoked function
}
// 'i' is 10 here
console.log(foo[0]()); // returns the reference to 'a' within the same scope, where the function was defined
In your first scenario, all of your functions added to the foo array are referencing the same var i. All functions will return whatever i was set to last, which is 10 because during the last iteration of the loop that's what it's value was set to.
In the second scenario, you are Immediately Invoking this function:
(function(){
var y =i;
foo[i] = function(){
return y;
}
})();
By immediately invoking it you are effectively locking in the local state of var y, for each iteration of the loop - it provides a unique scope for each function added to the array.
If I define an inner function inside a function, the inner function has access to the outer function's variables. If I want this inner function to be reusable and define it outside the outer function, the inner function now loses access to the outer function variables. How do I make this new reusable inner function have access to outside function variables, without passing those variables in as parameters?
function a () {
var x = [[1,2,3], [1,2,3], [1,2,3]];
var keys = Object.keys(x[0]);
for (var i = 0; i < x.length; i++) {
angular.forEach(keys, loop);
}
}
function loop (key) {
console.log(key, i);//i is undefined here
}
a();
Specifically, is there some way without 1) assigning variables to this, 2) without passing in variables as parameters, and 3) without creating global variables?
Edit: It seems there is no way to do this. But if I try another approach, to have the reusable function return a new function, I also do not have access to the inner scope. Why is this, and is there some way to make this work?
function a () {
var x = [[1,2,3], [1,2,3], [1,2,3]];
var keys = Object.keys(x[0]);
var myloop = loop();
for (var i = 0; i < x.length; i++) {
angular.forEach(keys, myloop);
}
}
function loop (key) {
return function(key) {
console.log(key, i);//i is undefined here
};
}
a();
In the following example, loop returns a function that closes over the value of i.
function a () {
var x = [[1,2,3], [1,2,3], [1,2,3]];
var keys = Object.keys(x[0]);
for (var i = 0; i < keys.length; i++) {
keys.forEach(loop(i));
}
}
function loop (i) {
return function (key) {
console.log(key, i); // i is now defined
}
}
a();
Output:
0 0
1 0
2 0
0 1
1 1
2 1
0 2
1 2
2 2
How do I make this new reusable inner function have access to outside function variables, without passing those variables in as parameters?
You can't. JavaScript has lexical scope, not dynamic scope.
See also: What is lexical scope?
I also want to make another option known which I just discovered. If you use .bind, you can curry the function with i, and the other variables will be passed in after the curried parameters.
....
angular.forEach(keys, loop.bind(null, i));
...
function loop(i, key) {
...
}
Inner functions are treated locally by the outer function. Therefore, you can access the variables belonging to the outer function from the inner function. But, once you have the inner function as a separate function outside the outer function, then you no longer have access to the private data variables of the outer function.
If this seems complicated, here is an example:
function A
{
//variables
function B
{
can use variables of A
}
}
But,
function A
{
//variables
}
function B
{
//cannot access variables of A
}
In JS (and many other languages), there is a visibility context. Possible contexts are e.g. "global" or function or block. These contexts are hierarchical, inner can read outer. Outer can never read inner (encapsulation principle) unless inner declares variable as global.
My question is based on two premises: (1) codes are not executed until the function containing them is called and (2) variables are saved in memory.
So, are variables initialized inside function declaration always re-initialized when the function execute?
To demonstrate, if I initialize a variable inside function declaration to a huge object and call that function, then, the huge object will be created, saved, or and processed in memory. If I call or execute that function many times, then the huge object will be created, saved, or and processed everytime the function executes. Then, there will be so many and big processing of that variable (containing that huge object, and if only one). Therefore, this behavior will result in bad effect for performance. I do not know much about this, is this correct?
This is to demonstrate with code:
If I declare global variables, then the process only involve value-changing. But, if I declare local variable like this:
var hugeObj = {
prop1 : function() {...},
prop2 : [...],
prop3 : {...},
};
and I execute the containing function five times, then there will be five "hugeObj" (with different contexts) in memory (and involve more processing).
Can you explain how variables are processed inside function declarations, and will them be created in every execution context?
The answer is yes, each time the function is run it's internal variables are re-initialized and are not reused.
function MyFunc(newValue){
var v;
if(newValue) v = newValue;
return v;
};
console.log(MyFunc()); // undefined
console.log(MyFunc(5)); // 5
console.log(MyFunc()); // undefined
// Therefore we can conclude that the object is re-initialized each time the function is run and its previous variable values are not reused.
If you would like it to not initialize the variable each time, just initialize the variable globally.
var v;
function MyFunc(newValue){
if(newValue) v = newValue;
return v;
};
console.log(MyFunc()); // undefined
console.log(MyFunc(5)); // 5
console.log(MyFunc()); // 5
In addition to the answer of #DustinPoissant, you can declare different scope (local or global) inside a function.
Let's use the same code as the answer:
function MyFunc(newValue){
var v;
if(newValue) v = newValue;
return v;
};
console.log(MyFunc()); // undefined
console.log(MyFunc(5)); // 5
console.log(MyFunc()); // undefined
In this case the scope is the local function, but if you remvoe var keyword, your scope changes to global (yes, v variable will be attached to window object):
function MyFunc(newValue){
if(newValue) v = newValue;
return v;
};
console.log(MyFunc()); // undefined
console.log(MyFunc(5)); // 5
console.log(MyFunc()); // 5
That's the same as write:
function MyFunc(newValue){
if(newValue) window.v = newValue;
return window.v;
};
console.log(MyFunc()); // undefined
console.log(MyFunc(5)); // 5
console.log(MyFunc()); // 5
Because one of the variables is stored externally, run both, one will maintain its values, the one with the variable initialised within the function is overwritten.
var array = ["1","2","3","4","5"];
function MyFunc()
{
var current = "0";
console.log("Iteration");
for(var i = 0; i < array.length; i++)
{
current += array[i];
console.log(current);
}
};
console.log(MyFunc());
console.log(MyFunc());
var array = ["1","2","3","4","5"];
var current = "0";
function MyFunc()
{
console.log("Iteration");
for(var i = 0; i < array.length; i++)
{
current += array[i];
console.log(current);
}
};
console.log(MyFunc());
console.log(MyFunc());
Variables are named memory, it all depend on the scope of the variable(Local or Global) Variables inside a functions are called local variables, every time this function is called the variables are re initialized, which means at every call to the function the value of the variable is expected to change.
public void myFunction(int val1, String val2)
{
int a = val1;
String b = val2;
System.out.println(val2 +" "+val1);
}
a and b in the above are local variable that will be affected base on the parameters passed to it by the method/function calls
so the value of a variables in a function will always change
Hi still i'm not sure about the exact usage of using closures in javascript.I have idea about closures "A closure is an inner function that has access to the outer (enclosing) function’s variables—scope chain".But i don't know why we are using closures in javascript.
It allows you to succinctly express logic without needing to repeat yourself or supply a large number of parameters and arguments for a callback function.
There is more information available here: javascript closure advantages?
Imagine if instead of
alert("Two plus one equals" + (2+1) );
you'd be forced to declare a variable for every constant you ever use.
var Two = 2;
var One = 1;
var myString = "Two plus one equals";
alert(myAlert + (Two + One) );
You'd go crazy if you had to define a variable for every single constant before you can ever use it.
The access to local variables in case of closures is an advantage, but the primary role - usefulness - is the use of a function as a primary expression, a constant.
Take
function Div1OnClick()
{
Counter.clickCount ++;
}
$('#Div1').click(Div1OnClick);
versus
$('#Div1').click(function(){ Counter.clickCount++; });
You don't create a new function name in the "above" namespace just to use it once. The actual activity is right there where it's used - you don't need to chase it across the code to where it was written. You can use the actual function as a constant instead of first defining and naming it and then calling it by name, and while there are countless caveats, advantages and tricks connected to closures, that's the one property that sells them.
In general, the main use of closures is to create a function that captures the state from it's context. Consider that the function has the captured variables but they are not passed as parameters.
So, you can think of it of a way to create families of functions. For example if you need a series of function that only differ in one value, but you cannot pass that value as a parameter, you can create them with closures.
The Mozilla Developer Network has a good introduction to closures. It shows the following example:
function init() {
var name = "Mozilla";
function displayName() {
alert(name);
}
displayName();
}
init();
In this case the function displayName has captured the variable name. As it stand this example is not very useful, but you can consider the case where you return the function:
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
Here the function makeFunc return the function displayName that has captured the variable name. Now that function can be called outside by assigning it to the variable myFunc.
To continue with this example consider now if the captured variable name were actually a parameter:
function makeFunc(name) {
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc("Mozilla");
myFunc();
Here you can see that makeFunc create a function that shows a message with the text passed as parameter. So it can create a whole family of function that vary only on the value of that variable ("Mozilla" in the example). Using this function we can show the message multiple times.
What is relevant here is that the value that will be shown in the massage has been encapsulated. We are protecting this value in a similar fashion a private field of a class hides a value in other languages.
This allows you to, for example, create a function that counts up:
function makeFunc(value) {
function displayName() {
alert(value);
value++;
}
return displayName;
}
var myFunc = makeFunc(0);
myFunc();
In this case, each time you call the function that is stored in myFunc you will get the next number, first 0, next 1, 2... and so on.
A more advanced example is the "Counter" "class" also from the Mozilla Developer Network. It demonstrates the module pattern:
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */
Here you can see that Counter is an object that has a method increment that advances the privateCounter variable, and the method decrement that decrements it. It is possible to query the value of this variable by calling the method value.
The way this is archived is with an auto-invocation of an anonymous function that creates a hidden scope where the varialbe privateCounter is declared. Now this variable will only be accessible from the functions that capture its value.
Closures are a powerful construct used to implement a lot of additional features in JavaScript. For instance a closure can be used to expose private state as follows:
function getCounter() {
var count = 0;
return function () {
return ++count;
};
}
var counter = getCounter();
alert(counter()); // 1
alert(counter()); // 2
alert(counter()); // 3
In the above example when we call getCounter we create a private variable count. Then we return a function which return count incremented. Hence the function we return is a closure in the sense that it closes over the variable count and allows you to access it even after count goes out of scope.
That's a lot of information stuffed in a few lines. Let's break it down?
Okay, so variables have a lifetime just like people do. They are born, they live and they die. The beginning scope marks the birth of a variable and the end of a scope marks the death of a variable.
JavaScript only has function scopes. Hence when you declare a variable inside a function it's hoisted to the beginning of the function (where it's born).
When you try to access a variable which is not declared you get a ReferenceError. However when you try to access a variable which is declared later on you get undefined. This is because declarations in JavaScript are hoisted.
function undeclared_variable() {
alert(x);
}
undeclared_variable();
When you try to access an undeclared variable you get a ReferenceError.
function undefined_variable() {
alert(x);
var x = "Hello World!";
}
undefined_variable();
When you try to access a variable which is declared later in the function you get undefined because only the declaration is hoisted. The definition comes later.
Coming back to scopes a variable dies when it goes out of scope (usually when the function within which the variable is declared ends).
For example the following program will give a ReferenceError because x is not declared in the global scope.
function helloworld() {
var x = "Hello World!";
}
helloworld();
alert(x);
Closures are interesting because they allow you to access a variable even when the function within which variable is declared ends. For example:
function getCounter() {
var count = 0;
return function () {
return ++count;
};
}
var counter = getCounter();
alert(counter()); // 1
alert(counter()); // 2
alert(counter()); // 3
In the above program the variable count is defined in the function getCounter. Hence when a call to getCounter ends the variable count should die as well.
However it doesn't. This is because getCounter returns a function which accesses count. Hence as long as that function (counter) is alive the variable count will stay alive too.
In this case the function which is returned (counter) is called a closure because it closes over the variable count which is called the upvalue of counter.
Uses
Enough with the explanation. Why do we need closures anyway?
As I already mentioned before the main use of closures is to expose private state as is the case with the getCounter function.
Another common use case of closures is partial application. For instance:
function applyRight(func) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
var rest = Array.prototype.slice.call(arguments);
return func.apply(this, rest.concat(args));
};
}
function subtract(a, b) {
return a - b;
}
var decrement = applyRight(subtract, 1);
alert(decrement(1)); // 0
In the above program we had a function called subtract. We used partial application to create another function called decrement from this subtract function.
As you can see the decrement function is actually a closure which closes over the variables func and args.
That's pretty much all you need to know about closures.
It is because of information hiding.
var myModule = (function (){
var privateClass = function (){};
privateClass.prototype = {
help: function (){}
};
var publicClass = function (){
this._helper = new privateClass();
};
publicClass.prototype = {
doSomething: function (){
this._helper.help();
}
};
return {
publicClass: publicClass
};
})();
var instance = new myModule.publicClass();
instance.doSomething();
In javascript you don't have classes with ppp (public, protected, private) properties so you have to use closures to hide the information. On class level that would be very expensive, so the only thing you can do for better code quality to use closure on module level, and use private helper classes in that closure. So closure is for information hiding. It is not cheap, it cost resources (memory, cpu, etc..) so you have to use closures just in the proper places. So never use it on class level for information hiding, because it is too expensive for that.
Another usage to bind methods to instances by using callbacks.
Function.prototype.bind = function (context){
var callback = this;
return function (){
return callback.apply(context, arguments);
};
};
Typical usage of bound function is by asynchronous calls: defer, ajax, event listeners, etc...
var myClass = function (){
this.x = 10;
};
myClass.prototype.displayX = function (){
alert(this.x);
};
var instance = new myClass();
setTimeout(instance.displayX.bind(instance), 1000); //alerts "x" after 1 sec
I am trying to increment a variable using Javascript, but I am not quite understanding what I am doing wrong. What do I need to change?
function init(){
var a = 0;
}
function repeat(){
a = a+1;
}
Do you want this ?
var a;
function init(){
a = 0;
}
function repeat(){
a = a+1;
}
If a is declared in a function, it's not available outside this function.
See the MDN on var :
The scope of a variable declared with var is the enclosing function
or, for variables declared outside a function, the global scope (which
is bound to the global object).
function init(){
var a=0;
a = repeat(a);
}
function repeat(a){
return a+1;
}
As mentioned above, access to variables declared inside a function is possible only inside this function. This rule also applies to curly braces.
Also to increment your value you may use postfix or prefix.
Postfix: x++ the increment operator increments and returns the value before incrementing.
Prefix ++x the increment operator increments and returns the value after incrementing.
{
let x = 0
x = myFunc(x)
}
function myFunc(a){
return a++
}
// next line will throw error because x was declared inside braces
// Uncaught ReferenceError: x is not defined
console.log(x)