closure or handler in object? - javascript

I click a button and there is a handler. I have never understood if I should use a closure, or let the handler be in a object. For example, in HTML I have,
<button id="b">Go</button>
<button id="c">Go</button>
and in JavaScript (with some jQuery),
var hdl=function(){
var hdl=function(){
foo+="foo"
console.log(foo)
},
foo=""
return hdl
}()
$("#b").click(hdl)
var obj={
bar:"",
hdl:function(){
this.bar+="bar"
console.log(this.bar)
}
}
var baz=function(){
obj.hdl()
}
$("#c").click(baz)
Both work. Or are there situations in which you can only use one of them?

An event handler is always a function or an object that implements the EventListener interface. I've never understood any reason to use an EventListener object rather than a function so I've only seen functions used, but you can use either.
If you choose a function, it's up to you whether you want a function to be a global function, an anonymously declared function or a function that is a property of an object. There is no "right" answer as it depends upon how you want to structure your code.
My event handlers are usually anonymously declared functions just because that's usually how I structure things and generally nothing more is needed. Simple is best so you should make it no more complicated than needed.
A closure is just a function body that survives longer than the simple execution of the function because some other function reference inside is still active. Whether to use a closure or not depends on your needs and again the structure of your code. Closures can be really handy ways of keeping some state without using global variables, but other times they aren't needed at all.

I think you're mixing up terms.
Closures are a natural result of JavaScript's scoping rules, not something you choose to create
The jQuery click event always takes a function. Whether that function is attached to an object—thereby making it a method—doesn't really matter. Depending on how that function is written, it may form a closure that affects you.
A closure is when a function "remembers" the variables in the context in which it's defined.
The classical closure example is something like this:
for(var i = 0; i < 10; i++)
$("#button" + i).click(function() { alert("you clicked button " + i); });
Most developers are surprised to learn that each button displays 10, which is the value of i when the outer scope ends. This happens because each of those functions declared in the loop has formed a closure over i. Those functions don't just get the value of i when they're declared, they get the actual i, in all its glory. That's why changing i after you create the function causes the created function to reflect the updated value of i
Situations like this are fixed by breaking the closure by passing i to a function, since function parameters are passed by value.
for(var i = 0; i < 10; i++)
(function(localI) {
$("#button" + i).click(function() { alert("you clicked button " + localI); });
)(i);

The only difference between your cases is that in one of them you are bundling your variables (foo) in an object. The following third example should make this point clear:
function hdl(variables){
variables.foo += variables.foo;
}
var obj = {foo: ""};
var baz = function(){
hdl(obj);
}
I don't think any of these alternatives is in anyway generally superior to the others. You should decide to use whatever solution is simpler and easier to understand and mantain depending on what your particular problem is.
For example, in the version using objects the variables are dinamically bound while in the version with closures they are statically bound. This means that the object version is more extensible (with inheritance, mixins, etc) while the closure version is more rigid (but simpler to reason about at compile time)

Related

Why is it not encouraged to create functions within a loop in JavaScript? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
I am an absolute newbie, and I just read this in JavaScript: The Good Parts.
In the chapter talking about scope, it says "It is important to understand that the inner function has access to the actual variables of the outer functions and not copies in order to avoid the following problem." And then the two following examples look like this:
//BAD EXAMPLE
var add_the_handlers = function (nodes) {
var i;
for (i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = function (e) {
alert(i);
};
}
};
//END BAD EXAMPLE
var add_the_handlers = function (nodes) {
var helper = function (i) {
return function (e) {
alert(i);
};
};
var i;
for (i = 0; i < nodes.length; i += 1) {
modes[i].onclick = helper(i);
}
};
According to the author the second example is better because it doesn't use a loop inside the function, otherwise it could be wasteful computationally. But I am at loss and don't know what to do with them. How do I put his theory in real application? Can anyone illustrate these two examples combine HTML?
The problem is with closure. The inner functions have access to the variable i defined outside of these functions. After all iterations of the loop have been executed, the variable i will hold the value of nodes.length. So when you click on nodes[0], the alert will say nodes.length, which is not what you'd expect. (You would expect the alert to say 0.) The same holds when you click on nodes[1], nodes[2], etc. The alert for all of them will say nodes.length.
Firstly, in the bad example, a function is created for each event handler; the loop creates multiple function objects. Whereas in the second example, a single function is created and referenced from inside the loop. So you save a lot of memory.
Secondly, in the bad example, as the value of "i" runs, the function does not retain the value, and when it runs, it will always return the last value of "i". In the good example however, as "i" is passed into the function, this value is retained as the lexical environment of the function, and when it is called, it will return the correct value.
Thirdly, as mentioned by #Gary Hayes, we might want to use the function elsewhere too. So it's best to keep it independent of the loop.
You can check it with HTML working here: https://jsfiddle.net/vdrr4519/.
'multifunc' elements are inited with example with many functions, 'singlefunc'—with a single one. See, we take all the elements with a class and pass them to the function.
multifunc(document.querySelectorAll('.multifunc'));
Function runs 'for' loop and adds 'click' event listener. So the element should alert its index on click (beginning from 0). But in example with many function a wrong value is produced (because of closure, other answers also highlight the issue).
I think I should say also that it's not issue of single function/mutliple functions—it's a question of working with closures. You see, I can implement a working example WITH many closures: https://jsfiddle.net/pr7gqtdr/1/. I do basically the same thing that you do in a single-function handler, but every time call the new 'helper' function:
nodes[i].onclick = function (i) {
return function (e) {
alert(i);
};
}(i);
See, this (i) at the end is an immediate function call, so onclick gets a function with i variable set in closure.
But, the single function options is a bit better, because it's more memory efficient, I guess. Functions are objects. If you create many of them, you take more memory, in general. So, choosing from these, I'd stick with 'handler' function option.
The bad example creates a lot of event handlers; One per event. The good example create a single event handler and assigns it to all the events.
With the bad example, you've created lots of separate functions, instead of just one. That can be a lot of extra overhead and a lot of potential scope problems. These include closure issues such as an event only firing for the last item in the loop.
Additionally, the good example allows you to more easily unsubscribe the events because you have access to the original function pointer.
The good example is also just easier to read and understand. The loop is only used for creating the elements and binding their events; The handling of those events is done elsewhere.
As Soviut mentions, you are creating lots of event handlers in the bad example. Moreover, it is important to point out that the bad example functions refer to the same i variable, which means all of them will have the last value of nodes.length when they execute.
This is because a closure is created. You can read more about it in Closures.

Definition of 'closures'

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/

deeper understanding of closure in Javascript

I was reading the comments on an answer and saw this comment:
[the closure] doesn't persist the state of foo so much as creates a special scope containing (1) the returned function and (2) all the external variables referenced at the time of the return. This special scope is called a closure.
OK, so far so good. Now here is the interesting part that I didn't know about:
Case in point... if you had another var defined in foo that was not referenced in the return function, it would not exist in the closure scope.
I guess that makes sense, but what implications does this have other than memory use / perfomance?
Question -- If all variables in scope were included in the closure, what would that allow me to do that I cannot do with the current model?
I think you're taking that comment too literally. The comment is just saying that you can't access it outside the function scope (it's not publicly accessible), not that its not available at all within the function. The returned function will have access to all of the outer functions scope no matter what. You just can't access that scope outside the outer function if the inner function doesn't provide a way of accessing it.
For instance, this expression evaluates to 4:
function testClosure(){
var x = 2;
return function(y){
alert(eval(y));
}
}
var closure = testClosure();
closure("x+2"); //4
http://jsfiddle.net/dmRcH/
So x is available despite not being directly referenced
Further research
It appears that chrome and firefox at least do attempt to optimize this in the sense that if you're not providing ANY way to reference the x variable, it doesn't show up as being available in the debugger. Running this with a breakpoint inside a closure shows x as unavailable on Chrome 26 and Firefox 18.
http://jsfiddle.net/FgekX/1/
But thats just a memory management detail, not a relevant property of the language. If there is any possible way that you could reference the variable, it is passed, and my suspicion is that other browsers may not optimize this in the same way. Its always better to code to the spec than to an implementation. In this case though the rule really is: "if there's any possible way for you to access it, it will be available". And also, don't use eval because it really will keep your code from optimizing anything.
if you had another var defined in foo that was not referenced in the return function, it would not exist in the closure scope.
This is not entirely accurate; the variable is part of the closure scope, even though it may not be directly referenced inside the function itself (by looking at the function code). The difference is how the engines optimize unused variables.
For instance, unused variables in the closure scope are known to cause memory leaks (on certain engines) when you're working with DOM elements. Take this classical example for instance:
function addHandler() {
var el = document.getElementById('el');
el.onclick = function() {
this.style.backgroundColor = 'red';
}
}
Source
In above code, memory is leaked (in both IE and Mozilla at least) because el is part of the closure scope for the click handler function, even though it's not referenced; this causes a cyclic reference which can't be removed because their garbage collection is based on reference counting.
Chrome, on the other hand, uses a different garbage collector:
In V8, the object heap is segmented into two parts: new space where objects are created, and old space to which objects surviving a garbage collection cycle are promoted. If an object is moved in a garbage collection cycle, V8 updates all pointers to the object.
This is also referred to as a generational or ephemeral garbage collector. Albeit more complicated, this type of garbage collector can more accurately establish whether a variable is used or not.
JavaScript has no inherent sense of privacy so we use function scope (closure) to simulate this functionality.
The SO answer you reference is an example of the Module pattern which Addy Osmani does a great job explaining the importance of in Learning JavaScript Design Patterns:
The Module pattern encapsulates "privacy", state and organization
using closures. It provides a way of wrapping a mix of public and
private methods and variables, protecting pieces from leaking into the
global scope and accidentally colliding with another developer's
interface. With this pattern, only a public API is returned, keeping
everything else within the closure private.
Please have a look below code:
for(var i=0; i< 5; i++){
setTimeout(function(){
console.log(i);
},1000);
}
Here what will be output? 0,1,2,3,4 not that will be 5,5,5,5,5 because of closure
So how it will solve? Answer is below:
for(var i=0; i< 5; i++){
(function(j){ //using IIFE
setTimeout(function(){
console.log(j);
},1000);
})(i);
}
Let me simple explain, when a function created nothing happen until it called so for loop in 1st code called 5 times but not called immediately so when it called i.e after 1 second and also this is asynchronous so before this for loop finished and store value 5 in var i and finally execute setTimeout function five time and print 5,5,5,5,5
Here how it solve using IIFE i.e Immediate Invoking Function Expression
(function(j){ //i is passed here
setTimeout(function(){
console.log(j);
},1000);
})(i); //look here it called immediate that is store i=0 for 1st loop, i=1 for 2nd loop, and so on and print 0,1,2,3,4
For more, please understand execution context to understand closure.
- There is one more solution to solve this using let (ES6 feature) but under the hood above function is worked
for(let i=0; i< 5; i++){
setTimeout(function(){
console.log(i);
},1000);
}
Output: 0,1,2,3,4

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!​

Should I encapsulate blocks of functionality in anonymous JavaScript functions?

My intuition is that it's a good idea to encapsulate blocks of code in anonymous functions like this:
(function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
})();
Because I'm not going to need aVar again, so I assume that the garbage collector will then delete aVar when it goes out of scope. Is this right? Or are interpreters smart enough to see that I don't use the variable again and clean it up immediately? Are there any reasons such as style or readability that I should not use anonymous functions this way?
Also, if I name the function, like this:
var operations = function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
};
operations();
does operations then necessarily stick around until it goes out of scope? Or can the interpreter immediately tell when it's no longer needed?
A Better Example
I'd also like to clarify that I'm not necessarily talking about global scope. Consider a block that looks like
(function() {
var date = new Date(); // I want to keep this around indefinitely
// And even thought date is private, it will be accessible via this HTML node
// to other scripts.
document.getElementById('someNode').date = date;
// This function is private
function someFunction() {
var someFuncMember;
}
// I can still call this because I named it. someFunction remains available.
// It has a someFuncMember that is instantiated whenever someFunction is
// called, but then goes out of scope and is deleted.
someFunction();
// This function is anonymous, and its members should go out of scope and be
// deleted
(function() {
var member;
})(); // member is immediately deleted
// ...and the function is also deleted, right? Because I never assigned it to a
// variable. So for performance, this is preferrable to the someFunction
// example as long as I don't need to call the code again.
})();
Are my assumptions and conclusions in there correct? Whenever I'm not going to reuse a block, I should not only encapsulate it in a function, but encapsulate it in an anonymous function so that the function has no references and is deleted after it's called, right?
You're right that sticking variables inside an anonymous function is a good practice to avoid cluttering up the global object.
To answer your latter two questions: It's completely impossible for the interpreter to know that an object won't be used again as long as there's a globally visible reference to it. For all the interpreter knows, you could eval some code that depends on window['aVar'] or window['operation'] at any moment.
Essentially, remember two things:
As long as an object is around, none of its slots will be magically freed without your say-so.
Variables declared in the global context are slots of the global object (window in client-side Javascript).
Combined, these mean that objects in global variables last for the lifetime of your script (unless the variable is reassigned). This is why we declare anonymous functions — the variables get a new context object that disappears as soon as the function finishes execution. In addition to the efficiency wins, it also reduces the chance of name collisions.
Your second example (with the inner anonymous function) might be a little overzealous, though. I wouldn't worry about "helping the garbage collector" there — GC probably isn't going to run in the middle that function anyway. Worry about things that will be kept around persistently, not just slightly longer than they otherwise would be. These self-executing anonymous functions are basically modules of code that naturally belong together, so a good guide is to think about whether that describes what you're doing.
There are reasons to use anonymous functions inside anonymous functions, though. For example, in this case:
(function () {
var bfa = new Array(24 * 1024*1024);
var calculation = calculationFor(bfa);
$('.resultShowButton').click( function () {
var text = "Result is " + eval(calculation);
alert(text);
} );
})();
This results in that gigantic array being captured by the click callback so that it never goes away. You could avoid this by quarantining the array inside its own function.
Anything that you add to the global scope will stay there until the page is unloaded (unless you specifically remove it).
It's generally a good idea to put variables and function that belong together either in a local scope or in an object, so that they add as little as possible to the global namespace. That way it's a lot easier to reuse code, as you can combine different scripts in a page with minimal risks for naming collisions.

Categories

Resources