Are closures too bad for browser's memory?
Is avoiding closures using bind in JavaScript a good way?
Existing code:
var oControl = new Control({
var self = this;
click: function(e){ //closure that's accessing self var
self.performAction();
}
});
I have been told to avoid writing code as shown above. Reason given - a closure is created in the above code. I have been suggested using bind to overcome the above problem.
Modified code:
var oControl = new Control({
var self = this;
click: function(e){ //Not a closure
this.performAction(); //Is this more readable?
}.bind(self)
});
I am not too sure if the modified code is more readable. Somehow, I feel that this is in a way polluted. Probably, there are better ways to avoid closures? But, is there a real need to avoid them in the first place?
I would suggest this:
var oControl = new Control({
click: this.performAction.bind(this)
});
There appears to be no reason in your code for the self variable at all and if the click handler is just going to call your other method, then you may as well use the .bind() without the wrapper function.
FYI, .bind() creates a closure itself so don't be thinking that using .bind() is eliminating a closure. It is eliminating you having to hand-code a closure variable which is what makes it handy to use and makes your code look cleaner.
As for your other questions:
Are closures too bad for browser's memory?
Closures do use some additional memory. Unless you have a zillion of them, that extra memory is not likely material. And, .bind() likely also uses a closure in its implementation (the this pointer has to be stored somewhere).
Is avoiding closures using bind in JavaScript a good way?
.bind() is very useful and you should feel free to use it when it serves your purpose. Whether to use your first block of code with your own closure variable, your second block of code with a wrapper function using .bind() or my suggestion is largely a matter of opinion on coding style and opinion on cleanliness of implementation. All can work fine and there is unlikely to be a meaningful difference in performance or memory usage.
Related
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);
}
I am trying to understand whether or not the concept behind using multiple initialization functions is bad practice. By an initialization function I mean either of the following:
$(document).ready(function(){
//... some code here
}
(function(){
//.... some code here
})();
Time and time again I have seen multiple initialization functions being used and I always thought that this is ultimately a bad practice, but am I really wrong?
Based on that, would anyone care to enlighten me as to whether is it a good or bad practice to use multiple initialization functions?
Edit: removed irrelevant example of a bad use of closure and encapsulation.
Your suspicion is correct in that it's generally a good idea to organize code when you can.
Centralizing initialization functions makes it easier for another developer to figure out which statements are being executed at any given time. This facilitates debugging and becomes increasingly important when multiple developers are working on the same code.
Perhaps consider doing something like this:
$(document).ready(function () {
function findLionelRichie() {
console.log('found Lionel Richie');
}
function findWhomeverElseNeedsFinding() {
console.log('found all the others');
}
(function initialize() {
findLionelRichie();
findWhomeverElseNeedsFinding();
})();
});
That being said, they cannot always be avoided (for example, when calling functions from external libraries). Try to keep it as organized as you can on your end, however.
Creating a function within another function changes the scope of the function in the same way it would change the scope of a variable.
The functions defined within another function won't be accessible outside the function unless they have been attached to an object that is accessible outside the function:
Background:
I have a self-taught hobbyist level of understanding of C++, which has translated into a similar understanding of javascript. As an attempt to understand javascript better, I decided to write a Greasemonkey script that would solve a problem with how Google handles multiple results from the same domain.
I wrote my script, and it was surprisingly easy. Now I feel like this script could be useful to others, so I'd like to release it. Before I do that though, I'd like to be certain I'm not releasing irresponsible code.
I know poor garbage collection is often cited as a problem with extensions, and did some research about what I would need to do in javascript to prevent that. It seems like the answer is any memory that is wrapped in a function will be reclaimed when that function exits. This seems to explain why a few popular scripts I looked at were wrapped in an otherwise useless function.
This leads me to these questions:
What should I do with my basic javascript function to ensure that it doesn't leak memory?
Is this, which I've seen in many scripts, an answer:
(function(){
//code goes here
})();
In the above code, what is the purpose of the first parentheses? It seems redundant to me.
While I was attempting to understand that line, I rewrote it as:
(function main(){
//code goes here
})
main();
The idea being that this was just calling the the previously unnamed function. This didn't work though, why?
I'm more interested in general answers, but in case it's needed here is my current code:
http://pastebin.com/qQWKfnJT
This pattern (wrapping a function in a pair of parenthesis and then placing another pair after the first pair) is called the " I mmediately I nvoked F unction E xpression" pattern (IIFE for short). What it does is define an anonymous function and then execute it immediately. The first set of parentheses mark the function as being an expression, rather than a statement. The second set execute the function returned from the first expression:
// This:
(function(){
// Todo: Add code
})();
// Translates *approximately* to this:
var _anonymous_function_2723113 = function() {
// Todo: Add code
};
_anonymous_function_2723113();
delete _anonymous_function_2723113;
As for why the function does not work when you give it a name, I would recommend reading up on kangaxx's article on the subject, especially where he touches on Named Function Expressions. The short of it is that when you have a named function expression (rather than a statement), the name is supposed to only be available to the function's scope.
So much for three and four - as for avoiding memory leaks, the IIFE is not a way to avoid memory leaks (as #elclanrs has pointed out, it merely helps you avoid polluting the global scope). To avoid memory leaks avoid circular references (and remember, closures can be a source of circular references).
Good luck, and enjoy yourself!
Here is an example, where anonymous functions can be used:
Lets have 4 elements with ids: id_1, id_2, id_3...
We want too loop over each of them and assign onclick event.
for (var i=0; i<5; i++) {
document.getElementById("id_"+i).onclick = function() {alert(i)}
}
When you click elements however each of them will alert the same - 4. The reason is that in the JavaScript closure only the last value is stored for local variables.
What you can do:
for (var i=0; i<5; i++) {
(function(n){
document.getElementById("id_"+n).onclick = function() {alert(n)};
})(i);
}
There are so many answers to this question in SO already... It's a self executing function. It's used in many cases to protect your code from the global scope. It's written in other ways too:
function(){}()
(function(){})()
(function(){}())
!function(){}()
(function(){}).call(this)
I've got pretty interesting question about EcmaScript-5 Function.prototype.bind implementation. Usually when you use bind, you do it this way:
var myFunction = function() {
alert(this);
}.bind(123);
// will alert 123
myFunction();
Okay so that's cool, but what is suppose to happen when we do this?
// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... 123!
myFunction();
I understand that it's completely logical behavior in terms of how Function.prototype.bind is implemented (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind). But in real life conditions it's completely useless behavior isn't it? The question is: is it bug or feature? If it's a bug, why it's nowhere mentioned? If it's a feature, why then Google Chrome with native "bind" implementation behaves absolutely the same way?
To make it more clear, what in my opinion would make more sense, here is the code snippet that implements Function.prototype.bind a little bit differently:
if (!Function.prototype.bind) {
Function.prototype.bind = function() {
var funcObj = this;
var original = funcObj;
var extraArgs = Array.prototype.slice.call(arguments);
var thisObj = extraArgs.shift();
var func = function() {
var thatObj = thisObj;
return original.apply(thatObj, extraArgs.concat(
Array.prototype.slice.call(
arguments, extraArgs.length
)
));
};
func.bind = function() {
var args = Array.prototype.slice.call(arguments);
return Function.prototype.bind.apply(funcObj, args);
}
return func;
};
}
So now try this:
// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... "foobar"
myFunction();
In my opinion, replacing "this" makes more sense...
So what do you guys think about it?
The precedent for Function.prototype.bind was the implementation of the idea in various JS frameworks. To the best of my knowledge, none of them allowed this-binding to be changed by subsequent binding. You might as well ask why none of them allowed this-binding changing, as to ask why ES5 doesn't allow it.
You're not the only person I've heard who thought this odd. Chris Leary, who works on Mozilla's JS engine (as I do), thought it a bit odd, raising the issue on Twitter a couple months ago. And in a somewhat different form, I remember one of the Mozilla Labs hackers questioning if there were some way to "unbind" a function, to extract the target function from it. (If you could do that, you could of course bind it to a different this, at least if you could also extract the bound arguments list to also pass it along.)
I don't remember the issue being discussed when bind was being specified. However, I wasn't paying particularly close attention to the es-discuss mailing list at the time this stuff was hashed out. That said, I don't believe ES5 was looking to innovate in the area much, just "pave a cowpath", to borrow a phrase.
You might possibly be able to propose some introspective methods to address these concerns to es-discuss, if you wrote a sufficiently detailed proposal. On the other hand, binding is a form of information-hiding mechanism, which would cut against its adoption. It might be worth a try to propose something, if you have time. My guess is the information-hiding concern would block a proposal from being adopted. But that's just a guess that could well be wrong. Only one way to find out...
When you bind a function, you ask for a new function that ignores it's own this pseudo argument and calls the original function with a fixed value for this.
Binding this function another time has exactly the same behaviour. If bind would somehow patch in a new this into it, it would have to special case for already-bound-functions.
In other words, bind works exactly the same on "normal" functions as it works on functions returned by bind, and in the absence of overriding factors, it's good engineering to keep the semantic complexity of a function low - it's easier to remember what bind does to a function if it treats all input functions in exactly the same way, as opposed to treating some input functions specially.
I think your confusion is that you view bind as modifying an existing function, and you therefore, if you modify it again you expect the original function to be modified again. However, bind does not modify anything, it creates a new function with specific behaviour. The new function is a function in it's own right, it's not a magic patched version of the original function.
As such, there is no mystery on why it was standardised or invented the way it was: bind returns a function that provides a new this and prepends arguments, and works the same on all functions. The simplest possible semantic.
Only this way is it actually safe to use - if bind would make a difference between already bound functions and "normal" ones, one would have to test before binding. A good example would be jQuery.each, which passes a new this. If bind would specialcase bound functions, there would be no safe way to pass a bound function into jQuery.each, as this will be overwritten on each call. To fix that, jQuery.each would have to specialcase bound functions somehow.
I am learning javascript and jquery and wondered whether it is good or bad practice to nest all my functions within $(document).ready(function). Is there any difference between this:
function someFunction()
{
return someThing;
}
$(document).ready(function()
{
// some code
...
someFunction();
});
and this:
$(document).ready(function()
{
// some code
...
function someFunction()
{
return someThing;
}
someFunction();
});
Be gentle - I'm pretty new to this!
You forgot at least one :-)
function someFunction()
{
return someThing;
}
$(someFunction);
Generally there is no difference between: $(document).ready(argFunc) and $(argFunc).
The other variations you listed have all different scopes for different things.
For example, in your 2nd block you declare someFunction inside a non-global scope, while your first and my example declare it in the global scope, which has implications for reachability.
Also, technically, with both of your variations you produce one extraneous function call. Because in this case, all you call is one function (which you can also write like my example).
UPDATE1:
To add some additional info and to further the discussion about scopes - JavaScript has very loose requirements for existence of variables. If it doesn't find them in the current scope, it wall just traverse the call chain upwards and look for it - until it finds it or not. That is why you can access the jQuery object ($) from anywhere.
There is however this:
someFunction($) {
// You can use $ here like always
return someThing;
}
$(someFunction);
This means, that the handlers (there can be more than one) for the document ready event of jQuery get passed jQuery itself as an argument.
If you specify this parameter for your function, you'll use that one, if you reference it. Otherwise, you are using the global one. That reduces the length of the upward look-up - chain.
That is completely irrelevant from a performance stand point.
But, by specifying this as a parameter, you make it absolutely clear where the jQuery object is coming from. Even that might be irrelevant.
I just wanted to show, that these callback-type functions in jQuery often take parameters that are useful.
So if you are ever stuck and need access to some object you don't have, it might be worthwhile to check the jQuery docs to see, if there is not a parameter, that does what you want.
To conclude this update, I very much like the first comment to the question, which is a much better answer than mine.
UPDATE2:
On the point of multiple callbacks for document ready (or any event binder in jQuery for that matter):
You can do this:
$(func1); // or $(document).ready(func1);
$(func2); // or $(document).ready(func2);
Both will get called as soon as jQuery fires its document ready event. That might come in handy depending on the perspective. Some would say, it encourages spreading your logic around. Others might say, it allows for cleaner separation of all the things that need to be done on document ready.
yes. The first way puts someFunction in the global scope so that it can be called by anyone. If you intend this function to be "private" and only callable by some code then the 2nd way is preferred. Generally you should prefer the 2nd way unless you need to export the function into global scope.
The differences are subtle, but worth bringing up.
Declared functions outside of DOM ready:
If you don't call the functions until DOM ready, then this is more efficient since it is registering the functions before waiting for the DOM to load (Edit: As is noted in the comments, there will be a slight performance penalty in accessing global variables due to scope resolution). This is very minor and probably not noticeable.
More importantly, you functions become globals, and you can clutter the global scope if you're not namespacing properly:
var myFuncs = {
someFunction : function() { ... },
someOtherFunciton : function() { ... }
};
Declared inside DOM ready:
Functions are no longer globals, but your functions are registered along with your other DOM ready code.
I would say it's fine to go either way in most cases, but definitely declare your functions under one namespace.
First off, functions are typically only declared if they are going to be used more than once. If you put a function inside the $(document).ready(function) then it won't be available outside the scope of the $(document).ready(function). Check out an article on Javascript Scope.
This is because $(document).ready accepts a function as a parameter and in your two examples you are declaring an inline function (that's the function () {} code in there). Check out a discussion of inline functions vs parameterized functions.
So, it boils down to deciding if you are going to use someFunction() more than once. If so, put it outside the $(document).ready function. Otherwise, you don't really need a function since you are just calling it once.
As long as someFunction() does not try to manipulate the dom, there is no difference. $(document).ready is called after all elements in the dom have loaded and can be accessed with javascript. If you try to manipulate an item in that page with javascript before it loads, it wont be there and the code will break.