I have used JS for two years and my pluralsight accessment rates me as proficient in JS, I understand prototypical inheritance, higher order functions, IIFEs etc and I have used them in real world instances but closures is one of those concept that you understand but can't find any reason why you would want to use them in real world development, I mean I know that if I say,
function expClosure(val){
//do something to val-->anotherVal
return function(val){return anotherVal)};
}
var exp = expClosure(val);
exp(); --> returns the value of anotherVal;
My question is why would I want to do this, or rather what specific instances can lead me to consider using this.
The main benefit to closures is you can "partially apply" a function using a closure, then pass the partially applied function around, instead of needing to pass the non-applied function, and any data you'll need to call it (very useful, in many scenarios).
Say you have a function f that will need in the future 2 pieces of data to operate. One approach is you could pass both pieces in as arguments when you call it. The problem with this approach is if the first piece of data is available immediately, and the second isn't, you'll have to pass it around with f so it's in scope when you want to call the function.
The other option is to give the available data to the function immediately. You can create a closure over the data, have the function reference the external data, then pass the function around by itself.
Option 2 is much simpler.
You can also use closures to implement static variables in functions in languages that don't natively support them. Clojure (the language) implements it's memoize function by having it return a modified version of the passed function that holds a reference to a map representing argument/return value pairs. Before the function is run, it first checks if the arguments already exist in the map. If they do, it returns the cached return value instead of recalculating it.
(Adapted from my answer to another question)
I wrote a bit about this in my practical bachelor thesis(2.2.2)
Hiding variables is a valuable usage of closure. Compared to some other languages variables can't be declared as private, public, etc. in JavaScript, but using closure you can hide variables that can only be used internally. E.g.
function Car() {
var speed = 0;
return {
accelerate: function() {
speed++;
}
}
}
var car = new Car();
car.accelerate();
speed is accessible by accelerate due to closure, but is otherwise completely inaccessible.
Since this question doesn't demand a programmatic answer, I am adding an answer and not a comment.
The example you quoted in the question is, I agree of a closure, and I am sure having access to pluralsight lectures, you well understand closures. So the aforestated example is not the only use case of closures. The closures are the functions which remember the scope in which they were created.
An obvious example of this is a callback registering mechanism which every one uses in jQuery. There are closures everywhere, and many of us have been unknowingly writing closures.
So if you have used redux, you would know the entire concept is based on closure, i.e. encapsulating the data(called state of application). Closure provisions a concept of private variables used in OOPS supporting languages.
I am adding another example of closure below, so you might be able to relate.
function processOrder(amount){
var temp_order_id = +new Date() + 'USERID';
var afterPaymentCompleteOrder = function(status){//callback
//afterPaymentCompleteOrder is a closure as it remembers the scope in which it is created when it is being called. So when ivoked it remembers the value of temp_order_id
if(status){
complete_order_method(temp_order_id);
}
else
delete_order_details(temp_order_id);
}
start_payment_process(amount, afterPaymentCompleteOrder);
}
Related
This question already has answers here:
Is it true that every function in JavaScript is a closure?
(2 answers)
Closed 3 years ago.
I recently interviewed a candidate for an entry level web developer position and asked this question: What might you call the following line of code in Javascript:
let foo = function() {}
The question was purposefully vague because the resume was weak and I wanted to get a sense of how the candidate worked through all of the possible answers to the question. After a few moments the response was essentially "I don't know, what's the right answer?"
I explained that there are a few answers: Variable declaration, function assignment, hoisting mitigation, ES6, etc. Then I said it could also be considered a closure. To that, the candidate responded, "I don't think that's a closure. A closure is a function inside of function."
It's the first time I've ever had a candidate challenge my response to a question to which they didn't know the answer and it made me wonder if a closure could be boiled down to a simple one liner. Am I wrong about that?
Edit: This is only for my own learning and has nothing to do with the candidate. In fact, we extended an offer and they accepted. They start next week :)
I think we can agree that a function doesn't have to be defines inside another function to be a closure. I'd probably have followed up and asked why they think that that's a requirement for being a closure and then direct the conversation towards scope in general.
People may have different opinions about what really constitutes a closure, but I like the description from Wikipedia (which used to be a bit more extensive) which I have been using whenever I teach JavaScript:
Operationally, a closure is a record storing a function together with an environment.
I like it because it is a very easy to understand description, and it applies easily to JavaScript functions, because that's exactly how it works as described in the spec. The spec even uses the term closure to refer to a created function, irrespectively of the actual content of the function.
And following that thought, every function in JavaScript is a closure, so you are right.
Having said that, I could see someone making the argument that this function is not used as a closure, since it doesn't access any free variables.
I also have to add that "closure" wouldn't be the first thing that comes to my mind when looking at this code. It's easier to name the things that are there vs that are not there (referring to the function not be used as a closure).
The first thing that would come to my mind is function expression.
https://en.wikipedia.org/wiki/Closure_(computer_programming)#Anonymous_functions
The term closure is often used as a synonym for anonymous function, though strictly, an anonymous function is a function literal without a name, while a closure is an instance of a function, a value, whose non-local variables have been bound either to values or to storage locations (depending on the language; see the lexical environment section below).
it's an anonymous function assigned to a block scoped variable, I guess it could be considered to be a closure, if it's in a block.
It is not a closure - it is merely an ‘anonymous’ function. However, the reason given is incorrect.
It is not a closure because it does not establish a lexical binding to a variable in an outer scope. The variable binding itself need not be mutable - although most closures (in JavaScript) employ variable reassignment.
Here is a minimally valid closure. See the quote and link given in other answer, as such is merely an extraction of a comment:
let a = 1
let f = () => a
This is a closure because a lexical binding is established. No secondary function is required. EOD/QED.
The variable (a) captured in the closure could refer to a mutable object. It could also be trivially written in a loop with the let having (loop) block scope. At no time is is there a requirement that the captured variable is itself reassignable (or even mutable): refer to Haskell and Java closures.
Here is a good example of closures in a loop that employ “let”: https://wesbos.com/for-of-es6/ Note that a secondary function is not required to establish a closure (which is a nice deviation from earlier ECMAScript versions).
If you want to consider that any type of function can be considered a closure, what is the point of using a homonymous term to talk about functions; and especially how to distinguish this specific type of coding done to protect its contents?
PO question: "the most minimal valid closure"
that I can do for the moment
answer for: MisterJojo OK thanks, can you give me an example of the most minimal valid closure? – Jeffrey Barrett
// prepared logic for specific closures functions
const fCount=_=>{let x=0;return _=>x++}
// closures functions :
let myCount = fCount()
let yourCount = fCount()
// proofs of ...
console.log( 'my', myCount() ) // 0
console.log( 'my', myCount() ) // 1
console.log( 'my', myCount() ) // 2
console.log( 'your', yourCount() ) // 0
console.log( 'your', yourCount() ) // 1
console.log( 'your', yourCount() ) // 2
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {min-height:100% !important; top:0;}
fCount is "closed" => there is no access to his 'x'.
this is why we call this kind of function code a "closure"
(in JS there is no private variables)
The javascript introduction says:
When I have code like below:
var Person=function(name){
this.name=name;
this.sayHello=function(){return 'Hello '+name;}
}
Whenever I instantiate a "Person", there will be a copy of "sayHello" function in the memory. To reduce this memory consumption, I can change the code like below:
var Person=(function(){
var sayHello=function(){return 'Hello '+name}
return function(name){
this.name=name
this.sayHello=sayHello
}
})()
In this way, there'll not be multiple copies of sayHello()
My questions are:
For the 1st type of code, what's the benefit except wasting more memory?
Should we write code in the 2nd way, or javascript should avoid one copy for one function per instance?
Thanks a lot.
The behavior you are witnessing is the result of two things:
Functions as first-class objects. This means functions are treated the same way as strings, numbers, arrays etc.
How local variables are treated in functions. Local variables are created (typically on the stack) each time the function is called. This allows functions to be called recursively.
This behavior exists in many different languages that have anonymous functions like Go, Perl, Lisp etc.
The two rules above means that each time you call your function the inner function gets created and assigned to the variable.
What's the advantage of this?
The primary advantage of this from the language point of view is consistency of behavior. It means functions are really treated as first-class objects just like numbers, strings etc. Treating it consistently means that people who try to use anonymous functions won't get surprised by the behavior.
How do people use this feature?
Sometimes you find yourself writing several different functions that look similar:
function double (x) {return x * 2};
function quadruple (x) {return x * 4};
Wouldn't it be nice to be able to categorize a "family" of functions that are similar and somehow write them once?
Well, in languages like C you may use a macro system to basically cut-and-paste the text you type to generate several different code.
In languages with first-class-functions you write a function to generate functions:
function makeMultiplier (factor) {
return function (x) { return x * factor }
}
So now you can do:
var double = makeMultiplier(2);
var quadruple = makeMultiplier(4);
Now OBVIOUSLY for this to work the makeMultiplier() function MUST return two different functions. It cannot just modify a single function to do different things each time it is called. Otherwise both the double() and quadruple() functions will multiply by 4 after the second call to makeMultiplier().
Implementation detail
It is possible to create a system whereby the body of inner functions are compiled only once and the differences are captured by a closure. So all functions only occupy RAM once but different versions of a function may occupy more than one closure. It is possible that this is how it's implemented by most js engines but I don't really know. If so, then inner functions do take up additional RAM each time they're defined but not by much (typically by one stack frame - so each function definition takes up the same space as a function call).
From the programmer's point of view though, inner functions must appear to work as if they're created each call because that's how you'd expect them to work.
For the 1st type of code, what's the benefit except wasting more memory?
The only time i'd use something like this is for quick testing of an anonymous object. An example of this would be in some sort of factory implementation:
getWidget = function(){
return {
foo: 'bar',
test: function(){ ... }
}
}
And honestly, this would be quickly replaced with proper coding conventions after I confirmed my initial testing.
Should we write code in the 2nd way, or javascript should avoid one copy for one function per instance?
I'd say no. Don't write code like this. It's unnecessarily convoluted and doesn't appear to work from what I can tell. I'd recommend just creating methods on the function prototype:
var Person = function(name){
this.name = name;
}
Person.prototype.sayHello = function(){
return 'Hello ' + this.name;
}
pros
- easy to read
- easy to manage
- this is scoped properly within the context of calling methods
cons
- a nominal increase in effort to code
- per a comment to the question, you lose access to variables scoped exclusively to the constructor
For the 1st type of code, what's the benefit except wasting more memory?
This could be used for access control (like private in some other languages).
Consider:
var Person=function(name){
this.sayHello = function(){return 'Hello '+name;}
};
name can only be accessed by sayHello, which is a opaque Function.
Other code may replace this.sayHello, but will not be able to let this sayHello instance use another name.
I'm trying to wrap my head around private variables in Javascript, temporary variables, and the GC. However, I can't quite figure out what would happen in the following situation:
MyClass = function() {
this.myProp = new createjs.Shape();
var tempVar = this.myProp.graphics;
tempVar.rect(0, 0, 10, 100);
tempVar = null;
var isDisposed = false;
this.dispose = function() {
if (isDisposed) return;
isDisposed = true;
}
}
var anInstance = new myClass();
My intention was to have isDisposed represent a private status variable, and tempVar be a use-and-throw variable.
Would tempVar get marked for GC? Would isDisposed be marked for GC too? How is the GC to know when I'm trying to declare a temporary variable meant for disposal, and when I'm trying to have a private variable within the object?
I tried to test the following in Chrome, and it seems as if tempVar never gets GC-ed as long as an instance of myClass exists. So I'm not sure what to believe now. I am incredulous that every single local variable that I create for temporary usage will exist in scope for the lifetime of the object.
Javascript does not have strongly typed objects. By setting tempVar to null, you're not declaring that you don't want to use it any more or marking it for collection as in Java or C#, you're merely assigning it a (perfectly valid) value. It's a trap to begin thinking that just because you made tempVar an "instance" of an object, that the variable is in fact an object and can be treated as such for its whole lifetime.
Basically, variables are just variables in Javascript. They can contain anything. It's like VB or VBScript in that regard. Scalars do undergo boxing in many cases (as in 'a|c'.split('|') making the string into a String) but for the most part, forget that. Functions are first-class objects meaning you can assign them to variables, return them from functions, pass them as parameters, and so on.
Now, to actually destroy something in Javascript, you either remove all references to it (as in the case of an object) or, in the case of an object's properties, you can remove them like this:
delete obj.propertyname;
// or //
delete obj[varContainingPropertyName];
To expand on that point, the following two code snippets achieve identical results:
function abc() {window.alert('blah');}
var abc = function() {window.alert('blah');}
Both create a local variable called abc that happens to be a function. The first one can be thought of as a shortcut for the second one.
However, according to this excellent article on deleting that you brought to my attention, you cannot delete local variables (including functions, which are really also local variables). There are exceptions (if the variable was created using eval, or it is in Global scope and you're not using IE <= 8, or you ARE using IE <= 8 and the variable was created in Global scope implicitly as in x = 1 which is technically a huge bug), so read the article for full details on delete, please.
Another key thing that may be of use to you is to know that in Javascript only functions have scope (and the window in browser implementations or whatever the global scope is in other implementations). Non-function objects and code blocks enclosed in { } do not have scope (and I say it this way since the prototype of Function is Object, so functions are objects too, but special ones). This means that, for example, considering the following code:
function doSomething(x) {
if (x > 0) {
var y = 1;
}
return y;
}
This will return 1 when executed with x > 0 because the scope of variable y is the function, not the block. So in fact it's wrong and misleading to put the var declaration in the block since it is in effect (though perhaps not true practice) hoisted to the function scope.
You should read up on closures in javascript (I cannot vouch for the quality of that link). Doing so will probably help. Any time a variable's function scope is maintained anywhere, then all the function's private variables are also. The best you can do is set them to undefined (which is more "nothing" than "null" is in Javascript) which will release any object references they have, but will not truly deallocate the variable to make it available for GC.
As for general GCing gotchas, be aware that if a function has a closure over a DOM element, and a DOM element somewhere also references that function, neither will be GCed until the page is unloaded or you break the circular reference. In some--or all?--versions of IE, such a circular reference will cause a memory leak and it will never be GCed until the browser is closed.
To try to answer your questions more directly:
tempVar will not be marked for GC until the function it is part of has all references released, because it is a local variable, and local variables in Javascript cannot be deleted.
isDisposed has the same qualities as tempVar.
There is no distinction in Javascript for "temporary variables meant for disposal". In newer versions of ECMAScript, there are actual getters and setters available, to define public (or private?) properties of a function.
A browser's console may provide you with misleading results, as discussed in the article on deleting with Firefox.
It's true, as incredible as it may be, that in Javascript, so long as a variable exists within a closure, that variable remains instantiated. This is not normally a problem, and I have not experienced browsers truly running out of memory due to tiny variables lying around un-garbage-collected. Set a variable to undefined when done with it, and be at ease--I sincerely doubt you will ever experience a problem. If you are concerned, then declare a local object var tmpObj = {tempVar: 'something'}; and when done with it you can issue a delete tmpObj.tempVar;. But in my opinion this will needlessly clutter your code.
Basically, my suggestion is to understand that in coming from other programming languages, you have preconceived notions about how a programming language ought to work. Some of those notions may have validity in terms of the ideal programming language. However, it is probably best if you relinquish those notions and just embrace, at least for now, how Javascript actually works. Until you are truly experienced enough to confidently violate the advice of those who have gone before you (such as I) then you're at greater risk of introducing harmful anti-patterns into your Javascript code than you are likely to be correcting any serious deficit in the language. Not having to Dispose() stuff could be really good news--it's this nasty pervasive task that Javascript simply doesn't require from you, so you can spend more time writing functionality and less time managing the lifetime of variables. Win!
I hope you take my words as kindly as they are meant. I don't by any means consider myself a Javascript expert--just that I have some experience and a solid competence in understanding how to use it and what the pitfalls are.
Thanks for listening!
I often come across Javascript code snippets that consist of many anonymous functions that are called where they are created, such as here:
var prealloc = (function() {
// some definitions here
return function prealloc_win(file, size, perms, sparseOk) {
// function body
};
})();
// can be called like this:
prealloc(...);
So this calls an anonymous function which returns another function prealloc_win. To me this seems equivalent to instantiating a class where the resulting object exposes the function prealloc_win:
function preallocObj() {
// some definitions here
this.prealloc_win = function(file, size, perms, sparseOk) {
// function body
};
}
prealloc = new preallocObj();
// can be called like this:
prealloc.prealloc_win(...);
Is this assumption correct? What are the benefits of using anonymous functions that are called directly? And why is this idiom so often seen in Javascript, but not often in other languages which could be written in the same way (C, C++, Python)?
The deal is that the preallocObj class says that this is something that could be
instantiated multiple times. I could just create more instances of it even though it wasn't really designed for that. You could do some hacks to prevent that but it's easier just to use the immediately invoked anonymous function for this.
With the immediately created and invoked anonymous function, a "class" is created, instantly "instantiated" and assigned to prealloc and
there is no way to reference the original anonymous function that created the prealloc object after this. It was created, invoked and lost.
You pretty much have the right idea. The benefits of this module pattern/function builder are that the resultant function can enclose its own internal definitions or state.
It's basically just a way to create a function with private variables or constants. Consider the less efficient alternative:
var prealloc = function() {
// some definitions here
// function body
}
Every time this function is called it would reassign/instantiate its variables, adding unnecessary performance overhead and overwriting any state data that resulted from previous calls.
This method is useful when there are some variables that are important to the workings of a function that you want only private access to or that you need to persist between invocations without contaminating the outer scope.
Javascript is fundamentally very different to C++, JAVA and Python and should be written in differnt ways. At the risk of repetition, Javascript is not an OOP language it is a prototype language. Douglas Crockford (inventor of JSON) at Yahoo has some wonderful articles and particuarily Videos entitled 'Javascript - the good parts' you should watch them all.
var name = function(n) {
var digits = ['one','two','three','four'];
return digits[n];
}
var namenew = (function() {
digits = ['one','two','three','four'];
return function(n) {
return digits[n];
}
}());
Both the versions result in the same output, however it is said that the second version is much faster than the first version.
As I understand, first version executes the function everytime where as the second version stores the result of execution. That is what confuses me as a functional/regular OOPS programmer.
How can one save a function with its inner context? What is happening under the hood? Can some one pls clarify?
The real answer to that question would be about 3 pages long. But I try to make it as short as possible. ECMA-/Javascript is all about Execution Contexts and Object. There are three basic types of Context in ECMAscript: Global context, Function contexts and eval contexts.
Every time you call a function, your engine will spawn it in it's own function context. Also, there is a such called Activation object created. This mystic object is part of a function context which consists out of at least:
[[Scope chain]]
Activation object
"this" context value
There may be more properties on different engines, but these three are required for any implementation of ES. However, back to the topic. If a function context is invoked, all parent contexts (or more precisly, the Activation objects from the parent contexts) are copied over into the [[Scope]] property. You can think of this property like an array, which holds (Activation-) Objects. Now, any function related information is stored in the Activation object (formal parameters, variables, function declarations).
In your example, the digits variable is stored in the Activation object for namenew. The second when the inner anonymous function is created, it adds that Activation object into its [[Scope]] propertys. When you call digits[n] there, Javascript first tries to find that variable in its own Activation object. If that fails, the search goes into the Scopechain. And voila, there we found the variable because we copied the AO from the outer function.
I already wrote too much for a short answer, but to really give a good answer to such a question you have to explain some basic knowledge about ES here. I guess that is just enough to give you an idea what really happens "under the hood" (there is a lot more to know, if you want to read more I'll give you some references).
You asked for it, you get it:
http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
The first function recreates digits every time it's executed. If it's a large array this is needlessly expensive.
The second function stores digits in a context shared only with namenew. Every time namenew is executed it only performs a single operation: return digits[n].
An example like this wont show any noticeable gains in performance, but with very large arrays/objects/function calls performance will be improved significantly.
In an OOP perspective using a closure in this manner is similar to storing data in a static variable.
Don't forget that namenew is receiving the result of the closure function. The closure itself is only executed once.