Definition of 'closures' - javascript

Let me ask one question. It's about closures in JavaScript, but not about how they work.
David Flanagan in his "JavaScript The Definitive Guide 6th Edition" wrote:
...Technically, all JavaScript functions are closures: they are objects, and they have a scope chain associated with them....
Is this correct? Can I call every function (function object + it's scope) a "closure"?
And stacks' tag "closures" says:
A closure is a first-class function that refers to (closes over) variables from the scope in which it was defined. If the closure still exists after its defining scope ends, the variables it closes over will continue to exist as well.
In JavaScript every function refers to variables from the scope in which it was defined. So, It's still valid.
The question is: why do so many developers think otherwise? Is there something wrong with this theory? Can't it be used as general definition?

Technically, all functions are closures. But if the function doesn't reference any free variables, the environment of the closure is empty. The distinction between function and closure is only interesting if there are closed variables that need to be saved along with the function code. So it's common to refer to functions that don't access any free variables as functions, and those that do as closures, so that you know about this distinction.

It's a tricky term to pin down. A function that's simply declared is just a function. What makes a closure is calling the function. By calling a function, space is allocated for the parameters passed and for local variables declared.
If a function simply returns some value, and that value is just something simple (like, nothing at all, or just a number or a string), then the closure goes away and there's really nothing interesting about it. However, if some references to parameters or local variables (which, mostly, are the same) "escape" the function, then the closure — that space allocated for local variables, along with the chain of parent spaces — sticks around.
Here's a way that some references could "escape" from a function:
function escape(x, y) {
return {
x: x,
y: y,
sum: function() { return x + y; }
};
}
var foo = escape(10, 20);
alert(foo.sum()); // 30
That object returned from the function and saved in "foo" will maintain references to those two parameters. Here's a more interesting example:
function counter(start, increment) {
var current = start;
return function() {
var returnValue = current;
current += increment;
return returnValue;
};
}
var evenNumbers = counter(0, 2);
alert(evenNumbers()); // 0
alert(evenNumbers()); // 2
alert(evenNumbers()); // 4
In that one, the returned value is itself a function. That function involves code that makes reference to the parameter "increment" and a local variable, "current".
I would take some issue with conflating the concept of a closure and the concept of functions being first-class objects. Those two things really are separate, though they're synergistic.
As a caveat, I'm not a formalist by basic personality and I'm really awful with terminology so this should probably be showered with downvotes.

I would try to answer your question knowing you were asked about what closures are during the interview (read it from the comments above).
First, I think you should be more specific with "think otherwise". How exactly?
Probably we can say something about this noop function's closure:
function() {}
But it seems it has no sense since there are no variables would bound on it's scope.
I think even this example is also not very good to consider:
function closureDemo() {
var localVar = true;
}
closureDemo();
Since its variable would be freed as there is no possibility to access it after this function call, so there is no difference between JavaScript and let's say C language.
Once again, since you said you have asked about what closures are on the interview, I suppose it would be much better to show the example where you can access some local variables via an external function you get after closureDemo() call, first. Like
function closureDemo() {
var localVar = true;
window.externalFunc = function() {
localVar = !localVar; // this local variable is still alive
console.log(localVar); // despite function has been already run,
// that is it was closed over the scope
}
}
closureDemo();
externalFunc();
externalFunc();
Then to comment about other cases and then derive the most common definition as it more likely to get the interviewer to agree with you rather than to quote Flanagan and instantly try to find the page where you've read it as a better proof of your statement or something.
Probably your interviewer just thought you don't actually know about what closures are and just read the definition from the book. Anyhow I wish you good luck next time.

The definition is correct.
The closure keeps the scope where it was born
Consider this simple code:
getLabelPrinter = function( label) {
var labelPrinter = function( value) {
document.write(label+": "+value);
}
return labelPrinter; // this returns a function
}
priceLabelPrinter = getLabelPrinter('The price is');
quantityLabelPrinter = getLabelPrinter('The quantity is');
priceLabelPrinter(100);
quantityLabelPrinter(200);
//output:
//The price is: 100 The quantity is: 200
https://jsfiddle.net/twqgeyuq/

Related

Javascript Function Declaration Options

I've seen experts using below to declare a function:
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
//etc
}());
e.g.
https://github.com/douglascrockford/JSON-js/blob/master/json.js
Could someone help me understand when should we use above pattern and how do we make use of it?
Thanks.
Well, since ECMA6 hasn't arrived yet, functions are about the best way to create scopes in JS. If you wrap a variable declaration of sorts in an IIFE (Immediately Invoked Function Expression), that variable will not be created globally. Same goes for function declarations.
If you're given the seemingly daunting task of clearing a script of all global variables, all you need to do is wrap the entire script in a simple (function(){/*script here*/}());, and no globals are created, lest they are implied globals, but that's just a lazy fix. This pattern is sooo much more powerful.
I have explained the use of IIFE in more detail both here, here and here
The basic JS function call live-cycle sort of works like this:
f();//call function
||
====> inside function, some vars are created, along with the arguments object
These reside in an internal scope object
==> function returns, scope object (all vars and args) are GC'ed
Like all objects in JS, an object is flagged for GC (Garbage Collection) as soon as that object is not referenced anymore. But consider the following:
var foo = (function()
{
var localFoo = {bar:undefined};
return function(get, set)
{
if (set === undefined)
{
return localFoo[get];
}
return (localFoo[get] = set);
}
}());
When the IIFE returns, foo is assigned its return value, which is another function. Now localFoo was declared in the scope of the IIFE, and there is no way to get to that object directly. At first glance you might expect localFoo to be GC'ed.
But hold on, the function that is being returned (and assigned to foo still references that object, so it can't be gc'ed. In other words: the scope object outlives the function call, and a closure is created.
The localFoo object, then, will not be GC'ed until the variable foo either goes out of scope or is reassigned another value and all references to the returned function are lost.
Take a look at one of the linked answers (the one with the diagrams), In that answer there's a link to an article, from where I stole the images I used. That should clear things up for you, if this hasn't already.
An IIFE can return nothing, but expose its scope regardless:
var foo = {};
(function(obj)
{
//obj references foo here
var localFoo = {};
obj.property = 'I am set in a different scope';
obj.getLocal = function()
{
return localFoo;
};
}(foo));
This IIFE returns nothing (implied undefined), yet console.log(foo.getLocal()) will log the empty object literal. foo itself will also be assigned property. But wait, I can do you one better. Assume foo has been passed through the code above once over:
var bar = foo.getLocal();
bar.newProperty = 'I was added using the bar reference';
bar.getLocal = function()
{
return this;
};
console.log(foo.getLocal().newProperty === bar.newProperty);
console.log(bar ==== foo.getLocal());
console.log(bar.getLocal() === foo.getLocal().getLocal());
//and so on
What will this log? Indeed, it'll log true time and time again. Objects are never copied in JS, their references are copied, but the object is always the same. Change it once in some scope, and those changes will be shared across all references (logically).
This is just to show you that closures can be difficult to get your head round at first, but this also shows how powerful they can be: you can pass an object through various IIFE's, each time setting a new method that has access to its own, unique scope that other methdods can't get to.
Note
Closers aren't all that easy for the JS engines to Garbage Collect, but lately, that's not that big of an issue anymore.
Also take your time to google these terms:
the module pattern in JavaScript Some reasons WHY we use it
closures in JavaScript Second hit
JavaScript function scope First hit
JavaScript function context The dreaded this reference
IIFE's can be named functions, too, but then the only place where you can reference that function is inside that function's scope:
(function init (obj)
{
//obj references foo here
var localFoo = {};
obj.property = 'I am set in a different scope';
obj.getLocal = function()
{
return localFoo;
};
if (!this.wrap)
{//only assign wrap if wrap/init wasn't called from a wrapped object (IE foo)
obj.wrap = init;
}
}(foo));
var fooLocal = foo.getLocal();
//assign all but factory methods to fooLocal:
foo.wrap(fooLocal);
console.log(fooLocal.getLocal());//circular reference, though
console.log(init);//undefined, the function name is not global, because it's an expression
This is just a basic example of how you can usre closures to create wrapper objects...
Well the above pattern is called the immediate function. This function do 3 things:-
The result of this code is an expression that does all of the following in a single statement:
Creates a function instance
Executes the function
Discards the function (as there are no longer any references to it after the statement
has ended)
This is used by the JS developers for creating a variables and functions without polluting the global space as it creates it's own private scope for vars and functions.
In the above example the function f(){} is in the private scope of the immediate function, you can't invoke this function at global or window scope.
Browser-based JavaScript only has two scopes available: Global and Function. This means that any variables you create are in the global scope or confined to the scope of the function that you are currently in.
Sometimes, often during initialization, you need a bunch of variables that you only need once. Putting them in the global scope isn't appropriate bit you don't want a special function to do it.
Enter, the immediate function. This is a function that is defined and then immediately called. That's what you are seeing in Crockford's (and others') code. It can be anonymous or named, without defeating the purpose of avoiding polluting the global scope because the name of the function will be local to the function body.
It provides a scope for containing your variables without leaving a function lying around. Keeps things clean.

What is the significance of declaring another function within a function with regards to closures in JavaScript?

I'm still struggling to wrap my mind around closures in JavaScript (for the record, I've read the answer to JavaScript closures here on Stack Overflow, plus the "JavaScript Closures for Dummies" and am still puzzled by them).
My main issue is that I'm having trouble understanding the significance of declaring another function within a function; I get that returning the inner function allows the local variables of the outer function to remain active, but isn't that still the case in this example?
function sayName(name) {
var say = "Hello, " + name;
alert(say);
}
var sayJohn = sayName("John");
The local variable, "say" is still being referenced outside of its local scope in the sayJohn() function that I've created.
So isn't this still creating a closure?
N.B I apologize for how garbled this all sounds, still very fresh to learning JavaScript and programming in general, so please go easy on me!
Your example indeed cannot show the power of closure.
Look at this instead:
function makeAdder(add1){
return function(add2){
return add1 + add2;
};
}
// add10 is a function which increments the input by 10(that's the closure's magic)
var add10 = makeAdder(10);
add10(12); // returns 22
add10(9); // returns 19
While #HuiZheng's answer is correct, here's a simpler use case for closures:
var getUniqueID = (function () {
var counter = 0;
return function () {
return counter++;
};
}());
getUniqueID(); // 0
getUniqueID(); // 1
getUniqueID(); // 2
say is not being referenced outside sayName function. "alert" is being called from inside sayName function and hence still in the scope of sayName.
closure is a function reference which keeps the outer function variables still active even after the outer function has been removed from the call-stack

How can I use closures with function pointers?

My goal is to use closures while still writing clean code. One thing I noticed is that somehow I always end up repeating myself because one of my anonymous functions is needed in more than one case.
To this goal, I want to have these repeated functions stored in an object which I can later reuse.
Now, to my question. I've created this example http://jsfiddle.net/tiagoespinha/tTx64/ and the alert will not fire, because y is null.
However, if I inline the function, everything works fine http://jsfiddle.net/tiagoespinha/tTx64/1/
Is there a trick to work around this? How can I have it working in the first example? The variable y is still there, why can't JS catch it?
You want objects having own variables (y) and sharing functions.
What you really need is probably prototype.
function Holder() {
this.y = 5;
this.myFn();
}
Holder.prototype.myFn = function() {
alert("The value of the closure var is " + this.y);
}
new Holder();
I'd suggest the reading of Introduction to Object-Oriented JavaScript so that you don't try to rebuild OOP with just closures.
//our constructor, each instance will carry a y of 5
function Proto() {
this.y = 5;
}
//a shared function for all instances
Proto.prototype.returnedFn = function() {
alert("The value of the closure var is " + this.y);
}
//just a wrapper for the new instance call.
//I just like it this way to avoid using "new" when making instances
function newFn() {
//return a new instance
return new Proto();
}
//test it out
newFn().returnedFn();
newFn().returnedFn();
Your first example would need some kind of dynamic scoping to work. Javascript is statically scoped.
Closures allow a function to capture some local variables from the scope it's defined in. Holder.myFn isn't defined in a scope that contains variable y.
Also note that every instance of a function has its own closure. Hence it's not possible to define your function once and have it refer to different y's in different contexts. (In your second example the inner function is defined every time you call newFn, so many instances can exist, each with its own copy of y.)
I will also add an answer to my own question to report my findings.
Based on the other solutions provided and partly using the OOP solution, I found another way which also makes use of closures.
// Object prototype which takes an argument
function MyObj(abc) {
// Declare function using a closure
// and thus being able to use the argument
this.myFn = (function(){
return function() {
alert("abc is " + abc);
};
})();
}
// Then we can simply create an object with the
// desired argument and the function will behave as expected
var v = new MyObj(10);
v.myFn();
I think nobody provided this solution possibly because I omitted that I don't really want to store the values locally in the object. I simply want to pass some values in, make use of them in one function and then get rid of the object.
In this case I believe a pure OOP solution might be overkill.
Anyhow, thank you for all the proposed solutions!​

Javascript "saves" function data in memory?

Example :
var myFunctArray=new Array();
for(var i=0; i<10; i++) {
addValues(i);
}
function addValues(myPoint)
{
myFunct=function () {
var myVar="Line " + myPoint;
console.log(myVar);
}
myFunctArray.push(myFunct);
}
myFunctArray[3]();
when I call the 4° function, how can it remembers the value of myPoint? In fact it is Line 3 the output, so myPoint value must be "stored" somewhere, for each function.
So, it stores 10 "definitions" of myFunct in the stack memory?
Hope it is clear what I mean.
It's called a closure. Any variables that are currently in scope when you create a new function are associated with that closure.
So, it stores 10 "definitions" of myFunct in the stack memory?
Yes, it does.
Your array contains ten closures, each of which has captured its own version of myPoint.
Thiefmaster answered your question pretty much. Yes, this code will use more and more memory, depending on how many closures your array contains. It has to be said that most modern engines will assign a reference to the function assigned to the MyFunct variable and a specific "call object" that contains the closure vars. In other words, your array will look something along the lines of:
myFuncArray[0] = {call:
{myPoint:'Whatever value was passed to the addValues function the first time'},
valueOf: myFunct};
//the actual value is a reference to myFunct
//JS provides an implicit link to the call property, which is bound to this particular reference
myFuncArray[1] = {call:
{myPoint:'The value passed to addValues the second time'},
valueOf: myFunct};
You don't have access to the object as such, but this is just the way to think of how JS will keep things organized in memory.
Slightly off topic, but you're creating an implied global with your MyFunct variable:
function addValues(myPoint)
{
var anotherClosureVar = 'This will be accessible, too: it\'s part of the closure';
var myFunct = function()
{//use var to declare in addValues scope, instead of using an implied global
var myVar="Line " + myPoint;
console.log(myVar);
console.log(anotherClosureVar);//will work, too
};
myFunctArray.push(myFunct);
}
All in all, if this is your code, memory shouldn't be that big of an issue. Even if this code were to run on an old JScript engine, it'll take some time before you've used up a meaningful amount of memory. Still, it's a good habit to think about stuff like this, and I do hope I made sense here, I'm not a native speaker, which makes explaining the more abstract aspects of JS somewhat tricky

garbage collection with node.js

I was curious about how the node.js pattern of nested functions works with the garbage collector of v8.
here's a simple example
readfile("blah", function(str) {
var val = getvaluefromstr(str);
function restofprogram(val2) { ... } (val)
})
if restofprogram is long-running, doesn't that mean that str will never get garbage collected? My understanding is that with node you end up with nested functions a lot. Does this get garbage collected if restofprogram was declared outside, so str could not be in scope? Is this a recommended practice?
EDIT I didn't intend to make the problem complicated. That was just carelessness, so I've modified it.
Simple answer: if value of the str is not referenced from anywhere else (and str itself is not referenced from restofprogram) it will become unreachable as soon as the function (str) { ... } returns.
Details: V8 compiler distinguishes real local variables from so called context variables captured by a closure, shadowed by a with-statement or an eval invocation.
Local variables live on the stack and disappear as soon as function execution completes.
Context variables live in a heap allocated context structure. They disappear when the context structure dies. Important thing to note here is that context variables from the same scope live in the same structure. Let me illustrate it with an example code:
function outer () {
var x; // real local variable
var y; // context variable, referenced by inner1
var z; // context variable, referenced by inner2
function inner1 () {
// references context
use(y);
}
function inner2 () {
// references context
use(z);
}
function inner3 () { /* I am empty but I still capture context implicitly */ }
return [inner1, inner2, inner3];
}
In this example variable x will disappear as soon as outer returns but variables y and z will disappear only when both inner1, inner2 and inner3 die. This happens because y and z are allocated in the same context structure and all three closures implicitly reference this context structure (even inner3 which does not use it explicitly).
Situation gets even more complicated when you start using with-statement, try/catch-statement which on V8 contains an implicit with-statement inside catch clause or global eval.
function complication () {
var x; // context variable
function inner () { /* I am empty but I still capture context implicitly */ }
try { } catch (e) { /* contains implicit with-statement */ }
return inner;
}
In this example x will disappear only when inner dies. Because:
try/catch-contains implicit with-statement in catch clause
V8 assumes that any with-statement shadows all the locals
This forces x to become a context variable and inner captures the context so x exists until inner dies.
In general if you want to be sure that given variable does not retain some object for longer than really needed you can easily destroy this link by assigning null to that variable.
Actually your example is somewhat tricky. Was it on purpose? You seem to be masking the outer val variable with an inner lexically scoped restofprogram()'s val argument, instead of actually using it. But anyway, you're asking about str so let me ignore the trickiness of val in your example just for the sake of simplicity.
My guess would be that the str variable won't get collected before the restofprogram() function finishes, even if it doesn't use it. If the restofprogram() doesn't use str and it doesn't use eval() and new Function() then it could be safely collected but I doubt it would. This would be a tricky optimization for V8 probably not worth the trouble. If there was no eval and new Function() in the language then it would be much easier.
Now, it doesn't have to mean that it would never get collected because any event handler in a single-threaded event loop should finish almost instantly. Otherwise your whole process would be blocked and you'd have bigger problems than one useless variable in memory.
Now I wonder if you didn't mean something else than what you actually wrote in your example. The whole program in Node is just like in the browser – it just registers event callbacks that are fired asynchronously later after the main program body has already finished. Also none of the handlers are blocking so no function is actually taking any noticeable time to finish. I'm not sure if I understood what you actually meant in your question but I hope that what I've written will be helpful to understand how it all works.
Update:
After reading more info in the comments on how your program looks like I can say more.
If your program is something like:
readfile("blah", function (str) {
var val = getvaluefromstr(str);
// do something with val
Server.start(function (request) {
// do something
});
});
Then you can also write it like this:
readfile("blah", function (str) {
var val = getvaluefromstr(str);
// do something with val
Server.start(serverCallback);
});
function serverCallback(request) {
// do something
});
It will make the str go out of scope after Server.start() is called and will eventually get collected. Also, it will make your indentation more manageable which is not to be underestimated for more complex programs.
As for the val you might make it a global variable in this case which would greatly simplify your code. Of course you don't have to, you can wrestle with closures, but in this case making val global or making it live in an outer scope common for both the readfile callback and for the serverCallback function seems like the most straightforward solution.
Remember that everywhere when you can use an anonymous function you can also use a named function, and with those you can choose in which scope do you want them to live.
My guess is that str will NOT be garbage collected because it can be used by restofprogram().
Yes, and str should get GCed if restofprogram was declared outside, except, if you do something like this:
function restofprogram(val) { ... }
readfile("blah", function(str) {
var val = getvaluefromstr(str);
restofprogram(val, str);
});
Or if getvaluefromstr is declared as something like this:
function getvaluefromstr(str) {
return {
orig: str,
some_funky_stuff: 23
};
}
Follow-up-question: Does v8 do just plain'ol GC or does it do a combination of GC and ref. counting (like python?)

Categories

Resources