Javascript Closures - javascript

I'm quite still confused with the concept of closure in JavaScript. I get the point that closure is the ability of the inner function to access the variable created within its mother function after the mother function has returned.
But I'm still confused why do we have to create inner function to protect the local variable if we could just create a variable inside the function?

We need to create an inner function so that the variables in the outer function have some existence after the outer function returns.
Consider a simple function:
function f() {
var x = 0;
return ++x; // x=1
} // Once the function has exited then "x" no longer exists.
Note that the variable "x" is only "active" (alive, existent) when control of the program flows from the start of the "f()" function to the end of it. But if we enclose "x" in an inner function then x will live as long as the inner function does:
function g() {
var x = 0;
return function() {
// Now "x" will live for as long as this function.
return ++x;
}
};
var counter = g();
counter(); // => 1
counter(); // => 2
counter(); // => 3
Now when we call "g()" we get another function, and "x" is active for as long as that function is referenced by a variable.

Why use closure?
(function(){
var current_page = 1;
function previous_page() {
current_page--;
// update interface
}
function next_page() {
current_page++;
// update interface
}
// a bit of jQuery, ok?
$('#previous').click(previous_page);
$('#next').click(next_page);
})();
Look: we have no global variables, not even any function defined in the global space... yet, we have attached a behaviour to the click events of "#previous" and "#next" buttons for a paging feature. How would you do it without closures? How would you do it defining current_page variable inside the functions?

You just answered your question, the inner function protects it's variable. jsFiddle
(function outer(){
var foo = 'bar';
function inner(){
var foo = 'OMG NO!';
}
alert(foo);//alerts 'bar'
})()

FROM MDN CLOSURES
why to use:
A closure lets you associate some data (the environment) with a function that operates on that data. This has obvious parallels to object oriented programming, where objects allow us to associate some data (the object's properties) with one or more methods.
when not to use
It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task as it will negatively affect script performance both in terms of processing speed and memory consumption.
For instance, when creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called the methods would get reassigned (that is, for every object creation).

The reason you need to create the inner function with scoped variables is object oriented encapsulation. It's essentially private variables.
The variables are "closed over".
// constructor function
var myObject = function(message) {
// private - scope is function level. It's CLOSED OVER the the inner function (closure).
// not delcared as a JSON property so not visible externally
var value = 0;
// constructor returns JSON object with public methods
// always constructed from the myObject var so it always hands back the same instance
// of the public methods
return {
// nested functions have access to outer function variables.
increment: function (inc) {
value ++;
},
getValue: function() {
return value;
},
// the inner function even has access to the outer function's args!
getMessage: message
}
};
Look at the return statement. It returns the public interface - some methods that have access to the private variable because they are in the inner function. It's using JavaScripts function scoped variable to create object oriented encapsulation.
After that I can it like:
var obj = myObject('Hello World');
obj.increment();
obj.increment();
console.log(obj.getValue());
console.log(obj.getMessage);
// should be undefined
console.log(obj.value);
Note at this point the consumer does not have access to the protected/encapsulated value or message.
Now, here's the kicker - the object is mutable so the caller can add methods or even replace methods. So, you would think someone could add a method that exposes the internals. But, they can't because of function scope (closure - they're closed over). Only the nested function has access to the variables of the outer function. So, if the caller adds a method to return the internal, they can't get access and it will be undefined.
The code above outputs:
2
Hello World
undefined
As a side note, I'm running the javascript with node.js
Here's a good blog post on the module pattern using closures:
http://www.yuiblog.com/blog/2007/06/12/module-pattern/

The point is that the variable is shared between the two functions. If you declared the variable in the inner function, then the outer function would not be able to access it, so it wouldn't be shared.

If you declared the variable in the inner function, then each call to the inner function would create a new variable: any modifications made by a previous call are lost.
But if the variable is declared in the outer function then multiple calls to the inner function would see the same variable and one call would see the modifications of a previous call so long as they were both scoped to the same version of the outer function.

There are alot of right answers out there about closures, but it always seems to get really technical while many people asking might be looking for a higher level simple explanation first.
I like to think of it like a car. When you drive a car, there are many many complex processes going on, but the average person doesn't need to know about these on an average day. Think of all those complexities as "private" variables hidden away by closures which makes the gas pedal, the break, the shifter, the steering wheel, and so on a lot easier to use.
So what is the purpose of a closure? To hide away all the complex variables and such to make a script much more usable. If you had to worry about every variable in a script everytime you wanted to use any function in the script, well that could quickly get very difficult. YAY CLOSURES!

Related

JavaScript "Class" "Private" Variable Scope

As we know, you can make a "Class" variable "private" in JavaScript by doing the following:
function ClassName(attribute){
var privateAttribute = attribute;
this.accessor = function(){
return privateAttribute;
}
this.mutator = function(x){
privateAttribute = x;
}
}
I know that this works, and I've used it before. But it kind of breaks down my understanding a tad. Aren't local variables supposed to go out of scope at the end of a function's execution? Shouldn't, according to how JavaScript scope is supposed to work, var privateAttribute be inaccessible by the time you try to call accessor from an instance of ClassName?
https://www.w3schools.com/js/js_scope.asp
What you are missing is that fact that a function can be called in several ways...
If your function is called as a function, then, yes, when the function ends, all its local data is gone.
But, if the function is called as a "constructor function":
var myObj = new ClassName(data);
Then the function creates an instance of an object, which is stored in the myObj object variable and all the function's private data is available (internally of course) until the object variable goes out of scope.
In addition to this, if a function contains a "closure" (a nested scope that refers to a variable from a higher scope) and that nested function winds up having a longer lifetime than the higher scope where the higher variable came from, then that variable cannot go out of scope even when the function it was defined in does. This concept trips a lot of people up at first, but it makes perfect sense - if a (let's say) returned function relies on data that would normally go out of scope when its block terminates, but the returned function lives longer than this, then the data will not and cannot be garbage collected.
Lastly, and really just to be clear, JavaScript does not actually have classes. It has prototypes and it is these prototypes that an object will inherit from. Because of how prototypes and inheritance work in JavaScript, your example code would really be written with methods being attached to the prototype, so that all instances of the object (created via a constructor function invocation) don't have to store the same function (thus, decreasing the memory footprint of those instances).
function ClassName(attribute){
// A regular variable will act as a private "class field"
var privateAttribute = attribute;
// But members that are attached to 'this' become instance fields
this.exposedPrivateData = privateAttribute;
}
// Methods get attached to the underlying prototype object that
// all instances of your object will inherit from
ClassName.prototype.accessor = function(){
return this.exposedPrivateData;
};
ClassName.mutator = function(x){
this.exposedPrivateData = x;
}

Javascript Closures (Object literal Vs Constructor based)

When using Javascript Closures, is there some difference in using Object literal Vs Constructor based objects ?
Are there just syntax difference OR is there some other difference as well for Closures?
Any example explaining the 2 differences would be really helpful.
Closures are a feature of functional programming. They have nothing to do with objects or object literals.
Read the following answer - it explains closures really well: https://stackoverflow.com/a/12931785/783743
In general a closure is a function which closes over the variables in a nested function which moves out of the scope of the closure. For example:
function getCounter() {
var count = 0;
return function counter() {
return ++count;
};
}
var counter = getCounter();
counter(); // 1
counter(); // 2
counter(); // 3
Here the function getCounter becomes a closure because it closes over the variable count used in the nested function counter when the nested function is returned (moves out of the scope of getCounter).
The variable which is closed over (in this case count) is called an upvalue. Closures are important because they allow values which would otherwise go out of scope (be garbage collected) to remain alive. This is not possible in languages like C/C++ and Java.
Closure is more about the function scope of the variable. So the important thing to know is that the scope of a variable is the function it was defined in. Any function that run inside this scope will have access to its parent function per se. Parent function won't have access to a child function variable, because it's outside of that child's scope.
Therefore a variable in an object literal, would be scoped to the function that it is contained it. (If it's not in a function, then it's in the global scope). A constructor is a function so any variables that it defines, is scoped in itself and inaccessible outside. Any inner methods that are in the constructor has access to those defined variables.
Closures are created when a function has access to a variable that is outside its own scope and that variable may be changed or altered by something else...even well after the function has finished execution.
I hope that helped some what.

An object constructor that takes parameters but has no "vars" inside the constructor body, where is the data?

Where is the data supplied by the argument being stored? Is a var first being created implicitly?
function Student(first){
this.getFirst = function(){
return first;
}
}
Tested with:
var myStudent = new Student("ross");
console.log(myStudent); // Student { getFirst=function() }
console.log(myStudent.getFirst()); // ross
console.log(first); // reference error, first not defined
console.log(myStudent.first); // undefined
for(var x in myStudent){
console.log(x);
} // getFirst
My second question is if I understand these correctly:
What happens with "var" variables inside a JavaScript Constructor?
“var” variables, "this" variables and "global" variables - inside a JavaScript Constructor
...is the getFirst function creates a closure and saves the state of the constructor's parameter value, if I use a var first in the constructor body is it okay to think of that as 'encapsulation'? Additionally, any inner function saves all the parameter values in a "closure state" or just the one's referenced by the inner function?
Thank you very much for your thoughts. This is my first question on S.O. but use the site almost daily as a reference, so thank you for that. My programming knowledge is limited so pardon if I've used crappy terms, happy to clarify where needed.
The first parameter is stored locally to the function that is your constructor, so anywhere inside Student() it will be in scope.
More interestingly, the the anonymous inner function that you're assigning to this.getFirst is closing over that value. Because of that, the inner function maintains a reference to the first variable even after the constructor is finished executing.
This works for regular functions too, not just constructors:
function makeCounter() {
var count = 1;
return function() { return count++; };
}
var counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
When used the right way, this approach can be used to achieve "private" variables in JavaScript, in the sense that the values captured in the closure are inaccessible from the outside.
Because of that, it turns out not to matter whether a closure captures all the variables in its scope or just the ones it uses, since you can't "reach inside" to those closed-over variables anyway. (Though in practice generally only the used values are captured, so that the runtime can garbage collect the rest, as they're unneeded.)
To get a little further into what you're asking, it's not about creating a var, but rather in your instance the function also keeps the arguments array.
Your functions can happily create closures over both.
By returning functions from your function, those returned functions (or objects with functions as methods) have access to any and all vars and arguments, as long as you don't overwrite those functions.
The magic of closures.

how does memory stacks work in javascript

When we have code like:
function a(){
var x =0;
this.add=function(){
alert(x++);
}
}
var test = new a();
test.add(); // alert 0
test.add(); // alert 1
test.add(); // alert 2
How does this work?
Doesn't that the value of 'x' in a() should be 'gone' as soon as test = new a() is complete? The stack contains x should also be gone as well, right? Or, does javascript always keep all the stacks ever created in case they will be referenced in future? But that wouldn't be nice, would it...?
The word you're looking for is “closure”.
Creating a function inside another function gives the inner function a (hidden) reference to the local scope in which the outer function was running.
As long as you keep a copy of your test, that has an explicit reference to the add function, and that function has an implicit reference to the scope created when calling the a constructor-function. That scope has an explicit reference to x, and any other local variables defined in the function. (That includes the this value and the constructor's arguments — though you can't access them from inside add as that function's own this/arguments are shadowing them.)
When you let go of test, the JavaScript interpreter can let go of x, because there's no way to get a reference back to that variable.
What you're seeing is the effect of a closure. The function being defined within the other function gets access to all of the variables and such in scope where it is — even after the outer function returns. More here, but basically, the variables (and arguments) in the function all exist as properties on an object (called the "variable object") related to that function call. Because the function you've bound to this.add is defined within that context, it has an enduring reference to that object, preventing the object from being garbage-collected, which means that that function can continue to access those properties (e.g., the variables and arguments to the function).
You normally hear people saying that the function closes over the x variable, but it's more complex (and interesting) than that. It's the access to the variable object that endures. This has implications. For instance:
function foo() {
var bigarray;
var x;
bigarray = /* create a massive array consuming memory */;
document.getElementById('foo').addEventListener('click', function() {
++x;
alert(x);
});
}
At first glance, we see that the click handler only ever uses x. So it only has a reference to x, right?
Wrong, the reference is to the variable object, which contains x and bigarray. So bigarray's contents will stick around as well, even though the function doesn't use them. This isn't a problem (and it's frequently useful), but it emphasizes the underlying mechanism. (And if you really don't need bigarray's contents within the click handler, you might want to do bigarray = undefined; before returning from foo just so the contents are released.)

Accessing variables from other functions without using global variables

I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.
If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?
I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
No one should yell at you for doing something like the above.
To make a variable calculated in function A visible in function B, you have three choices:
make it a global,
make it an object property, or
pass it as a parameter when calling B from A.
If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Consider using namespaces:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
Both local_function and global_function have access to all local and global variables.
Edit: Another common pattern:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.
What you're looking for is technically known as currying.
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.
I found this to be extremely helpful in relation to the original question:
Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
If another function needs to use a variable you pass it to the function as an argument.
Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.
If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.
Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...
Douglas Crockford wrote:
Jul 15 '06
"If you want to retrieve objects by id, then you should use an object, not an
array. Since functions are also objects, you could store the members in the
function itself."
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"The object can be obtained with"
objFacility.wlevine
The objects properties are now accessable from within any other function.
I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.
Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.
You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).
Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):
How to get a variable returned across multiple functions - Javascript/jQuery

Categories