JavaScript: inline functions vs predefined functionsWhat does this type of function mean in javascript?Nested Javascript Functions and jQueryJavaScript inline functions like in C++Best Practice for AngularJS Controllercreate a function for action creator in reduxHow do JavaScript closures work?What is the most efficient way to deep clone an object in JavaScript?How do I remove a property from a JavaScript object?var functionName = function() vs function functionName() Which equals operator (== vs ===) should be used in JavaScript comparisons?How do I include a JavaScript file in another JavaScript file?What does “use strict” do in JavaScript, and what is the reasoning behind it?How to check whether a string contains a substring in JavaScript?What is JSONP, and why was it created?How do I remove a particular element from an array in JavaScript?
How to use the passive form to say "This flower was watered."
Levenshtein Neighbours
Just one file echoed from an array of files
Virtual destructor moves object out of rodata section
Earliest evidence of objects intended for future archaeologists?
Spongy green glass found on graves
Does the Temple of the Gods spell nullify critical hits?
Do living authors still get paid royalties for their old work?
Quick destruction of a helium filled airship?
How can I train a replacement without them knowing?
My father gets angry everytime I pass Salam, that means I should stop saying Salam when he's around?
Starships without computers?
Is there a way to make the "o" keypress of other-window <C-x><C-o> repeatable?
Can I submit a paper computer science conference using an alias if using my real name can cause legal trouble in my original country
What happens to thrust and drag in a straight and level flight?
What security risks does exposing the size of the plaintext entail?
Peterhead Codes and Ciphers Club: Weekly Challenge
Did they show Truman doing private things (toilet, etc) when filming him for 24 hours, 7 days a week?
Replacing old plug-in 220V range with new hardwire 3-wire electric cooktop: remove outlet or add a plug?
Meaning of words заштырить and отштырить
How to add a table description to a longtable?
Repurpose telephone line to ethernet
Rotate List by K places
Tabularx with hline and overrightarrow vertical spacing
JavaScript: inline functions vs predefined functions
What does this type of function mean in javascript?Nested Javascript Functions and jQueryJavaScript inline functions like in C++Best Practice for AngularJS Controllercreate a function for action creator in reduxHow do JavaScript closures work?What is the most efficient way to deep clone an object in JavaScript?How do I remove a property from a JavaScript object?var functionName = function() vs function functionName() Which equals operator (== vs ===) should be used in JavaScript comparisons?How do I include a JavaScript file in another JavaScript file?What does “use strict” do in JavaScript, and what is the reasoning behind it?How to check whether a string contains a substring in JavaScript?What is JSONP, and why was it created?How do I remove a particular element from an array in JavaScript?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Can any body throw me some arguments for using inline functions against passing predefined function name to some handler.
I.e. which is better:
(function()
setTimeout(function() /*some code here*/ , 5);
)();
versus
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
Strange question, but we are almost fighting in the team about this.
javascript coding-style
add a comment |
Can any body throw me some arguments for using inline functions against passing predefined function name to some handler.
I.e. which is better:
(function()
setTimeout(function() /*some code here*/ , 5);
)();
versus
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
Strange question, but we are almost fighting in the team about this.
javascript coding-style
8
Nit-picking (and yet not): Both of those are inline functions, and neither is more predefined than the other. The only difference is that one of them is unnamed, the other one is named. It's a significant difference, though. (Good question, btw.)
– T.J. Crowder
Mar 29 '10 at 15:52
add a comment |
Can any body throw me some arguments for using inline functions against passing predefined function name to some handler.
I.e. which is better:
(function()
setTimeout(function() /*some code here*/ , 5);
)();
versus
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
Strange question, but we are almost fighting in the team about this.
javascript coding-style
Can any body throw me some arguments for using inline functions against passing predefined function name to some handler.
I.e. which is better:
(function()
setTimeout(function() /*some code here*/ , 5);
)();
versus
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
Strange question, but we are almost fighting in the team about this.
javascript coding-style
javascript coding-style
edited Mar 27 at 13:58
informatik01
13.5k8 gold badges57 silver badges94 bronze badges
13.5k8 gold badges57 silver badges94 bronze badges
asked Mar 29 '10 at 15:38
glaz666glaz666
4,37216 gold badges50 silver badges69 bronze badges
4,37216 gold badges50 silver badges69 bronze badges
8
Nit-picking (and yet not): Both of those are inline functions, and neither is more predefined than the other. The only difference is that one of them is unnamed, the other one is named. It's a significant difference, though. (Good question, btw.)
– T.J. Crowder
Mar 29 '10 at 15:52
add a comment |
8
Nit-picking (and yet not): Both of those are inline functions, and neither is more predefined than the other. The only difference is that one of them is unnamed, the other one is named. It's a significant difference, though. (Good question, btw.)
– T.J. Crowder
Mar 29 '10 at 15:52
8
8
Nit-picking (and yet not): Both of those are inline functions, and neither is more predefined than the other. The only difference is that one of them is unnamed, the other one is named. It's a significant difference, though. (Good question, btw.)
– T.J. Crowder
Mar 29 '10 at 15:52
Nit-picking (and yet not): Both of those are inline functions, and neither is more predefined than the other. The only difference is that one of them is unnamed, the other one is named. It's a significant difference, though. (Good question, btw.)
– T.J. Crowder
Mar 29 '10 at 15:52
add a comment |
13 Answers
13
active
oldest
votes
Named functions
There is some serious misuse of terminology in the question and answers on this page. There is nothing about whether or not a function is inline (a function expression) that says you cannot name it.
This is using a function expression:
setTimeout(function doSomethingLater() alert('In a named function.'); , 5);
and this is using a function statement:
function doSomethingLater() alert('In a named function.');
setTimeout(doSomethingLater, 5);
Both examples are using named functions and both get the same benefits when it comes to debugging and profiling tools!
If the name is specified (the text after "function" but before the parenthesis) then it is a named function regardless of whether it is inline or declared separately. If the name is not specified then it is "anonymous".
Note: T.J. points out that IE mishandles named function expressions in a non-trivial way (See: http://kangax.github.com/nfe/#jscript-bugs) and this is important to note, I'm simply trying to make a point about the terminology.
Which should you use?
In response to your direct question, you should use a named function statement if the function could ever be used from any other place in your code. If the function is being used in exactly one place and has no relevance anywhere else then I would use a function expression unless it is prohibitively long or otherwise feels out of place (for style reasons). If you use an inline function expression then it is often useful to name it anyway for the purposes of debugging or code clarity.
Memory leaks
Whether you name your function, use a function statement, or use a function expression has little impact on the memory leak issue. Let me try to explain what causes these leaks. Take a look at this code:
(function outerFunction()
var A = 'some variable';
doStuff();
)();
In the code above, when "outerFunction" finishes "A" goes out of scope and can be garbage collected, freeing that memory.
What if we add a function in there?
(function outerFunction()
var A = 'some variable';
setTimeout(function() alert('I have access to A whether I use it or not'); , 5);
)();
In this code (above) the function expression we are passing to setTimeout has a reference to "A" (through the magic of closure) and even after "outerFunction" finishes "A" will remain in memory until the timeout is triggered and the function is dereferenced.
What if we pass that function to something other than setTimeout?
(function outerFunction()
var A = 'some variable';
doStuff(function() alert('I have access to A whether I use it or not'); );
)();
function doStuff(fn)
someElement.onclick = fn;
Now the function expression we are passing to "doStuff" has access to "A" and even after "outerFunction" finishes "A" will remain in memory for as long as there is a reference to the function we passed into doStuff. In this case, we are creating a reference to that function (as an event handler) and therefore "A" will remain in memory until that event handler is cleared. (e.g. someone calls someElement.onclick = null)
Now look at what happens when we use a function statement:
(function outerFunction()
var A = 'some variable';
function myFunction() alert('I have also have access to A'); ;
doStuff(myFunction);
)();
The same problem! "myFunction" will be cleaned up only if "doStuff" does not hold a reference to it and "A" will only be cleaned up when "myFunction" is cleaned up. It does not matter whether we used a statement or an expression; what matters is if a reference to that function is created in "doStuff"!
1
Can you suggest how to void this memory leak issue?
– th1rdey3
Apr 3 '15 at 6:05
2
@th1rdey3, once you are aware of how scope is managed in javascript it becomes easier to avoid. The key is: Keep functions small and create your vars with the lowest visibility possible. This means: don't create globals, a function should only do one thing, and if a variable is only needed inside a function, var it inside that function. That's it.
– Prestaul
May 19 '15 at 17:36
1
I never thought of closures as memory leaks. They can be quite useful if you're aware of them.
– kamoroso94
May 12 '17 at 9:51
add a comment |
There is one significant difference between the two: The latter one has a name.
I like to help my tools help me, and so I mostly avoid anonymous functions as my tools can't give me meaningful information about them (for instance, in a call stack list in a debugger, etc.). So I'd go with the
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
...form in general. Rules are meant to be broken, though, not slavishly bowed to. :-)
Note that according to the specification, there's a third alternative: You can have an inline function that also has a name:
(function()
setTimeout(function invokeMe() /*some code here*/ , 5);
)();
The problem, though, is that every version so far of the JavaScript interpreter from Microsoft ("JScript"), including (astonishingly) the one in IE9, handles that named function expression incorrectly and creates two completely distinct functions at different times. (Proof, try it in IE9 or earlier and also in just about any other browser.) IE gets it wrong in two ways: 1. It creates two separate function objects, and 2. As a consequence of one of those, it "bleeds" the name symbol into the enclosing scope of the expression (in clear violation of Section 13 of the specification). Details here: Double take
+1 for the only objective answer.
– Mark
Mar 29 '10 at 16:50
@Mark: Thanks. Yours isn't objective? Seems like it is to me.
– T.J. Crowder
Mar 29 '10 at 16:55
@TJ The reuse is, but that's pretty obvious. At what point the abundance of names becomes pollution would be subjective, as well as any readability argument. It's hard to argue with more details in the stack trace.
– Mark
Mar 29 '10 at 16:58
+1 for this "Rules are meant to be broken, though, not slavishly bowed to"
– plodder
Mar 29 '10 at 21:50
There seems to be a misunderstanding of "named functions". Whether a function is inline (a function expression) or not (a function statement) does not affect whether or not it can be named.
– Prestaul
Jan 6 '12 at 23:08
|
show 5 more comments
IMO, declaring a function will be useful only if you intend to re-use it later, in some other way.
I personally use function expressions (first way) for setTimeout handlers.
However you might want to know the differences between function declarations and function expressions, I recommend you the following article:
- Named function expressions demystified
Naming a function is also the best way to avoid memory leaks.
– Egor Pavlikhin
Mar 31 '10 at 3:03
1
@HeavyWave: What you said needs clarification. It's true that functions that create closures are more prone to memory leaks (if you're not careful) and even if not causing a memory leak, they use more memory than they need (because you don't really usually need all the variables in the closure). However, naming a function does not mean you're avoiding the closure. Using a global named function does. But who wants write a serious js app with a bunch of global functions? It's OK for web page enhancement. In that case, though, memory is not much of a concern.
– Juan Mendes
Apr 2 '10 at 15:27
@Juan Mendes, you are totally right. I should have clarified what I meant. Of course, simply naming a function does not guarantee there will be no leaks. I just wanted to point out that abuse of anonymous functions can lead to serious memory leakage issues, which can be crucial for web applications.
– Egor Pavlikhin
Apr 2 '10 at 16:10
1
@Egor, there is absolutely nothing about anonymous functions (unnamed function expressions) that will lead to more memory leaks than named function statements. Those "leaks" are caused by closures that never leave scope and will or will not happen based on where the function is declared and the way the function is used, not the type of function you use.
– Prestaul
Jan 6 '12 at 23:04
@Juan, all functions create closures! What matters is whether or not the references to those functions go out of scope properly allowing those closures to be garbage collected and that has little to do with whether you use an expression or not.
– Prestaul
Jan 7 '12 at 0:09
|
show 6 more comments
I suggest a full duel between opposing team members to settle such arguments.
More seriously, in the end it just doesn't matter. The first form (non-named functions) tends to get unwieldy with larger functions, but isn't a big deal at all with small (1-2 line) functions. The second form is similarly harmless.
Any argument against either style is pure bikeshedding, imo.
2
+1 for combining a duel, a good answer and bike shed :) That's also how we got general approval here: by limiting inline function to a few lines.
– Danny T.
Mar 29 '10 at 15:47
+1 for the "full duel" comment. -1 for the bikeshedding comment. There is actually a very significant (read: non-trivial) difference between the two forms, even without reuse.
– T.J. Crowder
Mar 29 '10 at 15:48
1
@TJ Crowder - Sure, there are significant differences. My assumption was that the differences weren't really relevant to their debate (ie, both forms function similarly well in the case they are discussing, and some devs are just arguing based on style (even if they say otherwise)). But you're right "Any argument" is an exhaggeration. :)
– jsight
Mar 30 '10 at 13:38
Thanks for the bikeshedding link, somehow had not seen that before.
– Brian Moeskau
Mar 31 '10 at 3:08
add a comment |
An inline function avoids namespace pollution and predefined functions have higher reuse. I think you could make cases where each is appropriate.
In his example, there is basically no namespace pollution in either case. He has the whole thing wrapped in a scoping function, thereby creating a well-defined, contained namespace for the named function. No global is created.
– T.J. Crowder
Mar 29 '10 at 15:49
@T.J. True, but taking his example literally, there is nothing to debug in a call stack either and no information needed from the tools. ;)
– Mark
Mar 29 '10 at 16:29
We have no idea what complex logic is going to be where/*code*/is! :-) It may well call a function which calls another function which calls (etc., etc.), and he may well need to debug that. (Or it may just set the document title to "Foo!" which seems unlikely to need debugging.)
– T.J. Crowder
Mar 29 '10 at 16:32
@TJ: I know. :) I was more just trying to point out there are assumption made in all the answers. One being the code in/*code*/is non-trivial, and one that there is more enclosed in the scoping function than included in the example.
– Mark
Mar 29 '10 at 16:39
Ennh, okay. :-) But I will just point out that in the one case he did actually say (effectively) "There's code here." But still, as you say, assumptions.
– T.J. Crowder
Mar 29 '10 at 16:43
add a comment |
I think that the only difference in a code like that is that with the second piece of code you can re-call the same function (sometimes with "timer functions" it's useful):
(function()
function invokeMe()
if(..) setTimeout(invokeMe, 5);
setTimeout(invokeMe, 5);
)();
note that you can also do this witharguments.callee.
– Pointy
Mar 29 '10 at 15:49
1
@Pointy: True -- at a serious performance cost in nearly all implementations (we're talking orders of magnitude here), and not in the new "strict" mode.
– T.J. Crowder
Mar 29 '10 at 15:53
@TJ wow thanks, that's good to know
– Pointy
Mar 29 '10 at 16:11
@Pointy: Yeah, I was really shocked when I learned about the performance aspect.
– T.J. Crowder
Mar 29 '10 at 16:33
@TJ I'm guessing you've seen the stuff about IE w.r.t. named functions used as rvalues yura.thinkweb2.com/named-function-expressions still that's a really good article
– Pointy
Mar 29 '10 at 16:36
|
show 2 more comments
Can't we all just get along?
(function()
setTimeout( (function InvokeMe() /*some code here*/ ), 5);
)();
Only one thing really matters, IMO and that's ease of debug. A lot of step tracers won't be able to tell you anything about the func other than the fact that it was anonymous and had args but you can still define inline with a name by putting the definition in parens to force evaluation. For very simple or obvious breaking funcs, I suppose it's not a big deal but to me it's like semis. I really don't care what the other guy does if it doesn't cause pain but I try to always name my funcs because it's not hard and it can be an advantage.
add a comment |
I know, that this is an old question,
but to me there is an even more important difference than the ones already mentioned.
hoisting
Every function has to be created and therefore reserves some space in memory and eventually has to be GC later.
Named functions get hoisted to the beginning of the surrounding function, and are therefore created on every function call, wether they get used or not.
Anonymous functions get created only if the code that defines them is executed.
//an example where you wold prefer to use an anonymous function.
//you can assign this (anonymous) function to a variable, so you get your "name" back.
function someFn()
if(condition)
//the variable declaration has been hoisted,
//but the function is created at this point, and only if necessary.
var process = function(value)/* */;
switch(condition2)
case 1: process(valueFor1); break;
case 2: process(valueFor2); break;
/* ... */
function someFn()
var process;
if(condition)
process = function(value) /* A */
else
process = function(value) /* B */
//beware, depending on your code, "process" may be undefined or not a function
process(someValue);
//an example where you would prefer (/ utilize) the hoisting.
function someFn()
/* some code */
while(condition)
//some might want to keep the function definition near the code where it is used,
//but unlike an anonymous function or a lambda-expression this process-function
//is created only once per function-call, not once per iteration.
function process(value, index) /* ... */
/* ... */
process(value, index)
so, as a rule of thumb:
inside a loop there should be no anonymous function or lambda-expression
if you need the function only inside of a (rarely true) condition you should prefer anonymous functions over named ones, since they are only created when needed
if you know your buisness (JavaScript), you know when to ignore this advice
add a comment |
The predefined named functions can reduce the JavaScript callback hell issue, which is mentioned at http://callbackhell.com/
add a comment |
There are no technical reasons to prefer one version over the other. For me is usually depends on two things:
- I want to resuse the passed callback in another context. In this case I define the function standalone and pass the reference.
- The callback is larger than ~10 lines of code and the function expects additional arguments after the callback. In this case it is hard to reconstruct, which values are actually passed to the function.
Example:
setTimeout(function() // I need to scroll to see the other arguments
// many lines of code
, 0); // <- where does this '0' belong to?
1
Are there still editors which do not show matching parenthesis?
– ceving
Nov 18 '11 at 17:48
add a comment |
I prefer to use named functions. Named functions show by name on all debuggers (air, firebug, IE).
Example:
Notice that you can also have inline named functions like
method: function obj_method()
This way, when you look at the stack trace, you'll see function obj_method instead of anonymous.
Were you asking about when to inline a function rather than declare it? When it makes sense in the code. If you need it from two different places, it can't be inline. Sometimes inline make the code easier to read, sometimes harder.
@Juan: That named function expression (method: function obj_method()) doesn't work in most JavaScript implementations (including IE's JScript). It should work, arguably, but it doesn't. For more, see Juriy Zaytsev's article on NFEs: yura.thinkweb2.com/named-function-expressions (This link is actually in one of the other answers, and also in a comment on another answer.)
– T.J. Crowder
Mar 29 '10 at 22:46
@TJ I read the part about Function names in debuggers. That article explains that there are some quirks, it doesn't say that inline named functions don't work in IE. Most of the quirks can be worked around by making sure you never have two functions with the same name under the same scope. So if you have a block that will decide which function to return just name them accordingly, like addEventIE and addEventStandard and you'll be fine. The article actually says: "What it all boils down to is the fact that named function expressions is the only way to get a truly robust stack inspection."
– Juan Mendes
Apr 2 '10 at 15:21
add a comment |
I tend towards named functions as well. Anonymous function refs are quick, but should only be used for simple stuff. My rule of thumb is that if the function is more than 2 lines of code, it probably belongs in it's own definition.
This is complicated by most example code making use of Anonymous functions. But the samples are usually very simplistic. The method falls apart as things get more complicated. I've seen function refs nested in function refs as the developer realized that more callbacks were needed in subsequent steps. Instead of this tree based logic, I prefer the organization of isolated functions.
And usually end up happy that I can reuse one of the functions I define later.
One important use of an Anonymous Function is when you need to pass scoped data into your function call, but then I usually just wrap my function into the anonymous function.
Named functions are also absolutely necessary if you ever get into Test Driven Development.
add a comment |
In the example provided, the declaration and use of the function are so close that I think the only difference is readability. I prefer the second example.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2539205%2fjavascript-inline-functions-vs-predefined-functions%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
13 Answers
13
active
oldest
votes
13 Answers
13
active
oldest
votes
active
oldest
votes
active
oldest
votes
Named functions
There is some serious misuse of terminology in the question and answers on this page. There is nothing about whether or not a function is inline (a function expression) that says you cannot name it.
This is using a function expression:
setTimeout(function doSomethingLater() alert('In a named function.'); , 5);
and this is using a function statement:
function doSomethingLater() alert('In a named function.');
setTimeout(doSomethingLater, 5);
Both examples are using named functions and both get the same benefits when it comes to debugging and profiling tools!
If the name is specified (the text after "function" but before the parenthesis) then it is a named function regardless of whether it is inline or declared separately. If the name is not specified then it is "anonymous".
Note: T.J. points out that IE mishandles named function expressions in a non-trivial way (See: http://kangax.github.com/nfe/#jscript-bugs) and this is important to note, I'm simply trying to make a point about the terminology.
Which should you use?
In response to your direct question, you should use a named function statement if the function could ever be used from any other place in your code. If the function is being used in exactly one place and has no relevance anywhere else then I would use a function expression unless it is prohibitively long or otherwise feels out of place (for style reasons). If you use an inline function expression then it is often useful to name it anyway for the purposes of debugging or code clarity.
Memory leaks
Whether you name your function, use a function statement, or use a function expression has little impact on the memory leak issue. Let me try to explain what causes these leaks. Take a look at this code:
(function outerFunction()
var A = 'some variable';
doStuff();
)();
In the code above, when "outerFunction" finishes "A" goes out of scope and can be garbage collected, freeing that memory.
What if we add a function in there?
(function outerFunction()
var A = 'some variable';
setTimeout(function() alert('I have access to A whether I use it or not'); , 5);
)();
In this code (above) the function expression we are passing to setTimeout has a reference to "A" (through the magic of closure) and even after "outerFunction" finishes "A" will remain in memory until the timeout is triggered and the function is dereferenced.
What if we pass that function to something other than setTimeout?
(function outerFunction()
var A = 'some variable';
doStuff(function() alert('I have access to A whether I use it or not'); );
)();
function doStuff(fn)
someElement.onclick = fn;
Now the function expression we are passing to "doStuff" has access to "A" and even after "outerFunction" finishes "A" will remain in memory for as long as there is a reference to the function we passed into doStuff. In this case, we are creating a reference to that function (as an event handler) and therefore "A" will remain in memory until that event handler is cleared. (e.g. someone calls someElement.onclick = null)
Now look at what happens when we use a function statement:
(function outerFunction()
var A = 'some variable';
function myFunction() alert('I have also have access to A'); ;
doStuff(myFunction);
)();
The same problem! "myFunction" will be cleaned up only if "doStuff" does not hold a reference to it and "A" will only be cleaned up when "myFunction" is cleaned up. It does not matter whether we used a statement or an expression; what matters is if a reference to that function is created in "doStuff"!
1
Can you suggest how to void this memory leak issue?
– th1rdey3
Apr 3 '15 at 6:05
2
@th1rdey3, once you are aware of how scope is managed in javascript it becomes easier to avoid. The key is: Keep functions small and create your vars with the lowest visibility possible. This means: don't create globals, a function should only do one thing, and if a variable is only needed inside a function, var it inside that function. That's it.
– Prestaul
May 19 '15 at 17:36
1
I never thought of closures as memory leaks. They can be quite useful if you're aware of them.
– kamoroso94
May 12 '17 at 9:51
add a comment |
Named functions
There is some serious misuse of terminology in the question and answers on this page. There is nothing about whether or not a function is inline (a function expression) that says you cannot name it.
This is using a function expression:
setTimeout(function doSomethingLater() alert('In a named function.'); , 5);
and this is using a function statement:
function doSomethingLater() alert('In a named function.');
setTimeout(doSomethingLater, 5);
Both examples are using named functions and both get the same benefits when it comes to debugging and profiling tools!
If the name is specified (the text after "function" but before the parenthesis) then it is a named function regardless of whether it is inline or declared separately. If the name is not specified then it is "anonymous".
Note: T.J. points out that IE mishandles named function expressions in a non-trivial way (See: http://kangax.github.com/nfe/#jscript-bugs) and this is important to note, I'm simply trying to make a point about the terminology.
Which should you use?
In response to your direct question, you should use a named function statement if the function could ever be used from any other place in your code. If the function is being used in exactly one place and has no relevance anywhere else then I would use a function expression unless it is prohibitively long or otherwise feels out of place (for style reasons). If you use an inline function expression then it is often useful to name it anyway for the purposes of debugging or code clarity.
Memory leaks
Whether you name your function, use a function statement, or use a function expression has little impact on the memory leak issue. Let me try to explain what causes these leaks. Take a look at this code:
(function outerFunction()
var A = 'some variable';
doStuff();
)();
In the code above, when "outerFunction" finishes "A" goes out of scope and can be garbage collected, freeing that memory.
What if we add a function in there?
(function outerFunction()
var A = 'some variable';
setTimeout(function() alert('I have access to A whether I use it or not'); , 5);
)();
In this code (above) the function expression we are passing to setTimeout has a reference to "A" (through the magic of closure) and even after "outerFunction" finishes "A" will remain in memory until the timeout is triggered and the function is dereferenced.
What if we pass that function to something other than setTimeout?
(function outerFunction()
var A = 'some variable';
doStuff(function() alert('I have access to A whether I use it or not'); );
)();
function doStuff(fn)
someElement.onclick = fn;
Now the function expression we are passing to "doStuff" has access to "A" and even after "outerFunction" finishes "A" will remain in memory for as long as there is a reference to the function we passed into doStuff. In this case, we are creating a reference to that function (as an event handler) and therefore "A" will remain in memory until that event handler is cleared. (e.g. someone calls someElement.onclick = null)
Now look at what happens when we use a function statement:
(function outerFunction()
var A = 'some variable';
function myFunction() alert('I have also have access to A'); ;
doStuff(myFunction);
)();
The same problem! "myFunction" will be cleaned up only if "doStuff" does not hold a reference to it and "A" will only be cleaned up when "myFunction" is cleaned up. It does not matter whether we used a statement or an expression; what matters is if a reference to that function is created in "doStuff"!
1
Can you suggest how to void this memory leak issue?
– th1rdey3
Apr 3 '15 at 6:05
2
@th1rdey3, once you are aware of how scope is managed in javascript it becomes easier to avoid. The key is: Keep functions small and create your vars with the lowest visibility possible. This means: don't create globals, a function should only do one thing, and if a variable is only needed inside a function, var it inside that function. That's it.
– Prestaul
May 19 '15 at 17:36
1
I never thought of closures as memory leaks. They can be quite useful if you're aware of them.
– kamoroso94
May 12 '17 at 9:51
add a comment |
Named functions
There is some serious misuse of terminology in the question and answers on this page. There is nothing about whether or not a function is inline (a function expression) that says you cannot name it.
This is using a function expression:
setTimeout(function doSomethingLater() alert('In a named function.'); , 5);
and this is using a function statement:
function doSomethingLater() alert('In a named function.');
setTimeout(doSomethingLater, 5);
Both examples are using named functions and both get the same benefits when it comes to debugging and profiling tools!
If the name is specified (the text after "function" but before the parenthesis) then it is a named function regardless of whether it is inline or declared separately. If the name is not specified then it is "anonymous".
Note: T.J. points out that IE mishandles named function expressions in a non-trivial way (See: http://kangax.github.com/nfe/#jscript-bugs) and this is important to note, I'm simply trying to make a point about the terminology.
Which should you use?
In response to your direct question, you should use a named function statement if the function could ever be used from any other place in your code. If the function is being used in exactly one place and has no relevance anywhere else then I would use a function expression unless it is prohibitively long or otherwise feels out of place (for style reasons). If you use an inline function expression then it is often useful to name it anyway for the purposes of debugging or code clarity.
Memory leaks
Whether you name your function, use a function statement, or use a function expression has little impact on the memory leak issue. Let me try to explain what causes these leaks. Take a look at this code:
(function outerFunction()
var A = 'some variable';
doStuff();
)();
In the code above, when "outerFunction" finishes "A" goes out of scope and can be garbage collected, freeing that memory.
What if we add a function in there?
(function outerFunction()
var A = 'some variable';
setTimeout(function() alert('I have access to A whether I use it or not'); , 5);
)();
In this code (above) the function expression we are passing to setTimeout has a reference to "A" (through the magic of closure) and even after "outerFunction" finishes "A" will remain in memory until the timeout is triggered and the function is dereferenced.
What if we pass that function to something other than setTimeout?
(function outerFunction()
var A = 'some variable';
doStuff(function() alert('I have access to A whether I use it or not'); );
)();
function doStuff(fn)
someElement.onclick = fn;
Now the function expression we are passing to "doStuff" has access to "A" and even after "outerFunction" finishes "A" will remain in memory for as long as there is a reference to the function we passed into doStuff. In this case, we are creating a reference to that function (as an event handler) and therefore "A" will remain in memory until that event handler is cleared. (e.g. someone calls someElement.onclick = null)
Now look at what happens when we use a function statement:
(function outerFunction()
var A = 'some variable';
function myFunction() alert('I have also have access to A'); ;
doStuff(myFunction);
)();
The same problem! "myFunction" will be cleaned up only if "doStuff" does not hold a reference to it and "A" will only be cleaned up when "myFunction" is cleaned up. It does not matter whether we used a statement or an expression; what matters is if a reference to that function is created in "doStuff"!
Named functions
There is some serious misuse of terminology in the question and answers on this page. There is nothing about whether or not a function is inline (a function expression) that says you cannot name it.
This is using a function expression:
setTimeout(function doSomethingLater() alert('In a named function.'); , 5);
and this is using a function statement:
function doSomethingLater() alert('In a named function.');
setTimeout(doSomethingLater, 5);
Both examples are using named functions and both get the same benefits when it comes to debugging and profiling tools!
If the name is specified (the text after "function" but before the parenthesis) then it is a named function regardless of whether it is inline or declared separately. If the name is not specified then it is "anonymous".
Note: T.J. points out that IE mishandles named function expressions in a non-trivial way (See: http://kangax.github.com/nfe/#jscript-bugs) and this is important to note, I'm simply trying to make a point about the terminology.
Which should you use?
In response to your direct question, you should use a named function statement if the function could ever be used from any other place in your code. If the function is being used in exactly one place and has no relevance anywhere else then I would use a function expression unless it is prohibitively long or otherwise feels out of place (for style reasons). If you use an inline function expression then it is often useful to name it anyway for the purposes of debugging or code clarity.
Memory leaks
Whether you name your function, use a function statement, or use a function expression has little impact on the memory leak issue. Let me try to explain what causes these leaks. Take a look at this code:
(function outerFunction()
var A = 'some variable';
doStuff();
)();
In the code above, when "outerFunction" finishes "A" goes out of scope and can be garbage collected, freeing that memory.
What if we add a function in there?
(function outerFunction()
var A = 'some variable';
setTimeout(function() alert('I have access to A whether I use it or not'); , 5);
)();
In this code (above) the function expression we are passing to setTimeout has a reference to "A" (through the magic of closure) and even after "outerFunction" finishes "A" will remain in memory until the timeout is triggered and the function is dereferenced.
What if we pass that function to something other than setTimeout?
(function outerFunction()
var A = 'some variable';
doStuff(function() alert('I have access to A whether I use it or not'); );
)();
function doStuff(fn)
someElement.onclick = fn;
Now the function expression we are passing to "doStuff" has access to "A" and even after "outerFunction" finishes "A" will remain in memory for as long as there is a reference to the function we passed into doStuff. In this case, we are creating a reference to that function (as an event handler) and therefore "A" will remain in memory until that event handler is cleared. (e.g. someone calls someElement.onclick = null)
Now look at what happens when we use a function statement:
(function outerFunction()
var A = 'some variable';
function myFunction() alert('I have also have access to A'); ;
doStuff(myFunction);
)();
The same problem! "myFunction" will be cleaned up only if "doStuff" does not hold a reference to it and "A" will only be cleaned up when "myFunction" is cleaned up. It does not matter whether we used a statement or an expression; what matters is if a reference to that function is created in "doStuff"!
edited Jan 7 '12 at 0:29
answered Jan 6 '12 at 23:55
PrestaulPrestaul
68.4k9 gold badges71 silver badges81 bronze badges
68.4k9 gold badges71 silver badges81 bronze badges
1
Can you suggest how to void this memory leak issue?
– th1rdey3
Apr 3 '15 at 6:05
2
@th1rdey3, once you are aware of how scope is managed in javascript it becomes easier to avoid. The key is: Keep functions small and create your vars with the lowest visibility possible. This means: don't create globals, a function should only do one thing, and if a variable is only needed inside a function, var it inside that function. That's it.
– Prestaul
May 19 '15 at 17:36
1
I never thought of closures as memory leaks. They can be quite useful if you're aware of them.
– kamoroso94
May 12 '17 at 9:51
add a comment |
1
Can you suggest how to void this memory leak issue?
– th1rdey3
Apr 3 '15 at 6:05
2
@th1rdey3, once you are aware of how scope is managed in javascript it becomes easier to avoid. The key is: Keep functions small and create your vars with the lowest visibility possible. This means: don't create globals, a function should only do one thing, and if a variable is only needed inside a function, var it inside that function. That's it.
– Prestaul
May 19 '15 at 17:36
1
I never thought of closures as memory leaks. They can be quite useful if you're aware of them.
– kamoroso94
May 12 '17 at 9:51
1
1
Can you suggest how to void this memory leak issue?
– th1rdey3
Apr 3 '15 at 6:05
Can you suggest how to void this memory leak issue?
– th1rdey3
Apr 3 '15 at 6:05
2
2
@th1rdey3, once you are aware of how scope is managed in javascript it becomes easier to avoid. The key is: Keep functions small and create your vars with the lowest visibility possible. This means: don't create globals, a function should only do one thing, and if a variable is only needed inside a function, var it inside that function. That's it.
– Prestaul
May 19 '15 at 17:36
@th1rdey3, once you are aware of how scope is managed in javascript it becomes easier to avoid. The key is: Keep functions small and create your vars with the lowest visibility possible. This means: don't create globals, a function should only do one thing, and if a variable is only needed inside a function, var it inside that function. That's it.
– Prestaul
May 19 '15 at 17:36
1
1
I never thought of closures as memory leaks. They can be quite useful if you're aware of them.
– kamoroso94
May 12 '17 at 9:51
I never thought of closures as memory leaks. They can be quite useful if you're aware of them.
– kamoroso94
May 12 '17 at 9:51
add a comment |
There is one significant difference between the two: The latter one has a name.
I like to help my tools help me, and so I mostly avoid anonymous functions as my tools can't give me meaningful information about them (for instance, in a call stack list in a debugger, etc.). So I'd go with the
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
...form in general. Rules are meant to be broken, though, not slavishly bowed to. :-)
Note that according to the specification, there's a third alternative: You can have an inline function that also has a name:
(function()
setTimeout(function invokeMe() /*some code here*/ , 5);
)();
The problem, though, is that every version so far of the JavaScript interpreter from Microsoft ("JScript"), including (astonishingly) the one in IE9, handles that named function expression incorrectly and creates two completely distinct functions at different times. (Proof, try it in IE9 or earlier and also in just about any other browser.) IE gets it wrong in two ways: 1. It creates two separate function objects, and 2. As a consequence of one of those, it "bleeds" the name symbol into the enclosing scope of the expression (in clear violation of Section 13 of the specification). Details here: Double take
+1 for the only objective answer.
– Mark
Mar 29 '10 at 16:50
@Mark: Thanks. Yours isn't objective? Seems like it is to me.
– T.J. Crowder
Mar 29 '10 at 16:55
@TJ The reuse is, but that's pretty obvious. At what point the abundance of names becomes pollution would be subjective, as well as any readability argument. It's hard to argue with more details in the stack trace.
– Mark
Mar 29 '10 at 16:58
+1 for this "Rules are meant to be broken, though, not slavishly bowed to"
– plodder
Mar 29 '10 at 21:50
There seems to be a misunderstanding of "named functions". Whether a function is inline (a function expression) or not (a function statement) does not affect whether or not it can be named.
– Prestaul
Jan 6 '12 at 23:08
|
show 5 more comments
There is one significant difference between the two: The latter one has a name.
I like to help my tools help me, and so I mostly avoid anonymous functions as my tools can't give me meaningful information about them (for instance, in a call stack list in a debugger, etc.). So I'd go with the
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
...form in general. Rules are meant to be broken, though, not slavishly bowed to. :-)
Note that according to the specification, there's a third alternative: You can have an inline function that also has a name:
(function()
setTimeout(function invokeMe() /*some code here*/ , 5);
)();
The problem, though, is that every version so far of the JavaScript interpreter from Microsoft ("JScript"), including (astonishingly) the one in IE9, handles that named function expression incorrectly and creates two completely distinct functions at different times. (Proof, try it in IE9 or earlier and also in just about any other browser.) IE gets it wrong in two ways: 1. It creates two separate function objects, and 2. As a consequence of one of those, it "bleeds" the name symbol into the enclosing scope of the expression (in clear violation of Section 13 of the specification). Details here: Double take
+1 for the only objective answer.
– Mark
Mar 29 '10 at 16:50
@Mark: Thanks. Yours isn't objective? Seems like it is to me.
– T.J. Crowder
Mar 29 '10 at 16:55
@TJ The reuse is, but that's pretty obvious. At what point the abundance of names becomes pollution would be subjective, as well as any readability argument. It's hard to argue with more details in the stack trace.
– Mark
Mar 29 '10 at 16:58
+1 for this "Rules are meant to be broken, though, not slavishly bowed to"
– plodder
Mar 29 '10 at 21:50
There seems to be a misunderstanding of "named functions". Whether a function is inline (a function expression) or not (a function statement) does not affect whether or not it can be named.
– Prestaul
Jan 6 '12 at 23:08
|
show 5 more comments
There is one significant difference between the two: The latter one has a name.
I like to help my tools help me, and so I mostly avoid anonymous functions as my tools can't give me meaningful information about them (for instance, in a call stack list in a debugger, etc.). So I'd go with the
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
...form in general. Rules are meant to be broken, though, not slavishly bowed to. :-)
Note that according to the specification, there's a third alternative: You can have an inline function that also has a name:
(function()
setTimeout(function invokeMe() /*some code here*/ , 5);
)();
The problem, though, is that every version so far of the JavaScript interpreter from Microsoft ("JScript"), including (astonishingly) the one in IE9, handles that named function expression incorrectly and creates two completely distinct functions at different times. (Proof, try it in IE9 or earlier and also in just about any other browser.) IE gets it wrong in two ways: 1. It creates two separate function objects, and 2. As a consequence of one of those, it "bleeds" the name symbol into the enclosing scope of the expression (in clear violation of Section 13 of the specification). Details here: Double take
There is one significant difference between the two: The latter one has a name.
I like to help my tools help me, and so I mostly avoid anonymous functions as my tools can't give me meaningful information about them (for instance, in a call stack list in a debugger, etc.). So I'd go with the
(function()
function invokeMe()
/*code*/
setTimeout(invokeMe, 5);
)();
...form in general. Rules are meant to be broken, though, not slavishly bowed to. :-)
Note that according to the specification, there's a third alternative: You can have an inline function that also has a name:
(function()
setTimeout(function invokeMe() /*some code here*/ , 5);
)();
The problem, though, is that every version so far of the JavaScript interpreter from Microsoft ("JScript"), including (astonishingly) the one in IE9, handles that named function expression incorrectly and creates two completely distinct functions at different times. (Proof, try it in IE9 or earlier and also in just about any other browser.) IE gets it wrong in two ways: 1. It creates two separate function objects, and 2. As a consequence of one of those, it "bleeds" the name symbol into the enclosing scope of the expression (in clear violation of Section 13 of the specification). Details here: Double take
edited Jan 7 '12 at 0:22
answered Mar 29 '10 at 15:45
T.J. CrowderT.J. Crowder
730k133 gold badges1323 silver badges1391 bronze badges
730k133 gold badges1323 silver badges1391 bronze badges
+1 for the only objective answer.
– Mark
Mar 29 '10 at 16:50
@Mark: Thanks. Yours isn't objective? Seems like it is to me.
– T.J. Crowder
Mar 29 '10 at 16:55
@TJ The reuse is, but that's pretty obvious. At what point the abundance of names becomes pollution would be subjective, as well as any readability argument. It's hard to argue with more details in the stack trace.
– Mark
Mar 29 '10 at 16:58
+1 for this "Rules are meant to be broken, though, not slavishly bowed to"
– plodder
Mar 29 '10 at 21:50
There seems to be a misunderstanding of "named functions". Whether a function is inline (a function expression) or not (a function statement) does not affect whether or not it can be named.
– Prestaul
Jan 6 '12 at 23:08
|
show 5 more comments
+1 for the only objective answer.
– Mark
Mar 29 '10 at 16:50
@Mark: Thanks. Yours isn't objective? Seems like it is to me.
– T.J. Crowder
Mar 29 '10 at 16:55
@TJ The reuse is, but that's pretty obvious. At what point the abundance of names becomes pollution would be subjective, as well as any readability argument. It's hard to argue with more details in the stack trace.
– Mark
Mar 29 '10 at 16:58
+1 for this "Rules are meant to be broken, though, not slavishly bowed to"
– plodder
Mar 29 '10 at 21:50
There seems to be a misunderstanding of "named functions". Whether a function is inline (a function expression) or not (a function statement) does not affect whether or not it can be named.
– Prestaul
Jan 6 '12 at 23:08
+1 for the only objective answer.
– Mark
Mar 29 '10 at 16:50
+1 for the only objective answer.
– Mark
Mar 29 '10 at 16:50
@Mark: Thanks. Yours isn't objective? Seems like it is to me.
– T.J. Crowder
Mar 29 '10 at 16:55
@Mark: Thanks. Yours isn't objective? Seems like it is to me.
– T.J. Crowder
Mar 29 '10 at 16:55
@TJ The reuse is, but that's pretty obvious. At what point the abundance of names becomes pollution would be subjective, as well as any readability argument. It's hard to argue with more details in the stack trace.
– Mark
Mar 29 '10 at 16:58
@TJ The reuse is, but that's pretty obvious. At what point the abundance of names becomes pollution would be subjective, as well as any readability argument. It's hard to argue with more details in the stack trace.
– Mark
Mar 29 '10 at 16:58
+1 for this "Rules are meant to be broken, though, not slavishly bowed to"
– plodder
Mar 29 '10 at 21:50
+1 for this "Rules are meant to be broken, though, not slavishly bowed to"
– plodder
Mar 29 '10 at 21:50
There seems to be a misunderstanding of "named functions". Whether a function is inline (a function expression) or not (a function statement) does not affect whether or not it can be named.
– Prestaul
Jan 6 '12 at 23:08
There seems to be a misunderstanding of "named functions". Whether a function is inline (a function expression) or not (a function statement) does not affect whether or not it can be named.
– Prestaul
Jan 6 '12 at 23:08
|
show 5 more comments
IMO, declaring a function will be useful only if you intend to re-use it later, in some other way.
I personally use function expressions (first way) for setTimeout handlers.
However you might want to know the differences between function declarations and function expressions, I recommend you the following article:
- Named function expressions demystified
Naming a function is also the best way to avoid memory leaks.
– Egor Pavlikhin
Mar 31 '10 at 3:03
1
@HeavyWave: What you said needs clarification. It's true that functions that create closures are more prone to memory leaks (if you're not careful) and even if not causing a memory leak, they use more memory than they need (because you don't really usually need all the variables in the closure). However, naming a function does not mean you're avoiding the closure. Using a global named function does. But who wants write a serious js app with a bunch of global functions? It's OK for web page enhancement. In that case, though, memory is not much of a concern.
– Juan Mendes
Apr 2 '10 at 15:27
@Juan Mendes, you are totally right. I should have clarified what I meant. Of course, simply naming a function does not guarantee there will be no leaks. I just wanted to point out that abuse of anonymous functions can lead to serious memory leakage issues, which can be crucial for web applications.
– Egor Pavlikhin
Apr 2 '10 at 16:10
1
@Egor, there is absolutely nothing about anonymous functions (unnamed function expressions) that will lead to more memory leaks than named function statements. Those "leaks" are caused by closures that never leave scope and will or will not happen based on where the function is declared and the way the function is used, not the type of function you use.
– Prestaul
Jan 6 '12 at 23:04
@Juan, all functions create closures! What matters is whether or not the references to those functions go out of scope properly allowing those closures to be garbage collected and that has little to do with whether you use an expression or not.
– Prestaul
Jan 7 '12 at 0:09
|
show 6 more comments
IMO, declaring a function will be useful only if you intend to re-use it later, in some other way.
I personally use function expressions (first way) for setTimeout handlers.
However you might want to know the differences between function declarations and function expressions, I recommend you the following article:
- Named function expressions demystified
Naming a function is also the best way to avoid memory leaks.
– Egor Pavlikhin
Mar 31 '10 at 3:03
1
@HeavyWave: What you said needs clarification. It's true that functions that create closures are more prone to memory leaks (if you're not careful) and even if not causing a memory leak, they use more memory than they need (because you don't really usually need all the variables in the closure). However, naming a function does not mean you're avoiding the closure. Using a global named function does. But who wants write a serious js app with a bunch of global functions? It's OK for web page enhancement. In that case, though, memory is not much of a concern.
– Juan Mendes
Apr 2 '10 at 15:27
@Juan Mendes, you are totally right. I should have clarified what I meant. Of course, simply naming a function does not guarantee there will be no leaks. I just wanted to point out that abuse of anonymous functions can lead to serious memory leakage issues, which can be crucial for web applications.
– Egor Pavlikhin
Apr 2 '10 at 16:10
1
@Egor, there is absolutely nothing about anonymous functions (unnamed function expressions) that will lead to more memory leaks than named function statements. Those "leaks" are caused by closures that never leave scope and will or will not happen based on where the function is declared and the way the function is used, not the type of function you use.
– Prestaul
Jan 6 '12 at 23:04
@Juan, all functions create closures! What matters is whether or not the references to those functions go out of scope properly allowing those closures to be garbage collected and that has little to do with whether you use an expression or not.
– Prestaul
Jan 7 '12 at 0:09
|
show 6 more comments
IMO, declaring a function will be useful only if you intend to re-use it later, in some other way.
I personally use function expressions (first way) for setTimeout handlers.
However you might want to know the differences between function declarations and function expressions, I recommend you the following article:
- Named function expressions demystified
IMO, declaring a function will be useful only if you intend to re-use it later, in some other way.
I personally use function expressions (first way) for setTimeout handlers.
However you might want to know the differences between function declarations and function expressions, I recommend you the following article:
- Named function expressions demystified
edited Oct 18 '12 at 22:58
Nick DeVore
6,4953 gold badges33 silver badges41 bronze badges
6,4953 gold badges33 silver badges41 bronze badges
answered Mar 29 '10 at 15:42
CMSCMS
624k166 gold badges858 silver badges819 bronze badges
624k166 gold badges858 silver badges819 bronze badges
Naming a function is also the best way to avoid memory leaks.
– Egor Pavlikhin
Mar 31 '10 at 3:03
1
@HeavyWave: What you said needs clarification. It's true that functions that create closures are more prone to memory leaks (if you're not careful) and even if not causing a memory leak, they use more memory than they need (because you don't really usually need all the variables in the closure). However, naming a function does not mean you're avoiding the closure. Using a global named function does. But who wants write a serious js app with a bunch of global functions? It's OK for web page enhancement. In that case, though, memory is not much of a concern.
– Juan Mendes
Apr 2 '10 at 15:27
@Juan Mendes, you are totally right. I should have clarified what I meant. Of course, simply naming a function does not guarantee there will be no leaks. I just wanted to point out that abuse of anonymous functions can lead to serious memory leakage issues, which can be crucial for web applications.
– Egor Pavlikhin
Apr 2 '10 at 16:10
1
@Egor, there is absolutely nothing about anonymous functions (unnamed function expressions) that will lead to more memory leaks than named function statements. Those "leaks" are caused by closures that never leave scope and will or will not happen based on where the function is declared and the way the function is used, not the type of function you use.
– Prestaul
Jan 6 '12 at 23:04
@Juan, all functions create closures! What matters is whether or not the references to those functions go out of scope properly allowing those closures to be garbage collected and that has little to do with whether you use an expression or not.
– Prestaul
Jan 7 '12 at 0:09
|
show 6 more comments
Naming a function is also the best way to avoid memory leaks.
– Egor Pavlikhin
Mar 31 '10 at 3:03
1
@HeavyWave: What you said needs clarification. It's true that functions that create closures are more prone to memory leaks (if you're not careful) and even if not causing a memory leak, they use more memory than they need (because you don't really usually need all the variables in the closure). However, naming a function does not mean you're avoiding the closure. Using a global named function does. But who wants write a serious js app with a bunch of global functions? It's OK for web page enhancement. In that case, though, memory is not much of a concern.
– Juan Mendes
Apr 2 '10 at 15:27
@Juan Mendes, you are totally right. I should have clarified what I meant. Of course, simply naming a function does not guarantee there will be no leaks. I just wanted to point out that abuse of anonymous functions can lead to serious memory leakage issues, which can be crucial for web applications.
– Egor Pavlikhin
Apr 2 '10 at 16:10
1
@Egor, there is absolutely nothing about anonymous functions (unnamed function expressions) that will lead to more memory leaks than named function statements. Those "leaks" are caused by closures that never leave scope and will or will not happen based on where the function is declared and the way the function is used, not the type of function you use.
– Prestaul
Jan 6 '12 at 23:04
@Juan, all functions create closures! What matters is whether or not the references to those functions go out of scope properly allowing those closures to be garbage collected and that has little to do with whether you use an expression or not.
– Prestaul
Jan 7 '12 at 0:09
Naming a function is also the best way to avoid memory leaks.
– Egor Pavlikhin
Mar 31 '10 at 3:03
Naming a function is also the best way to avoid memory leaks.
– Egor Pavlikhin
Mar 31 '10 at 3:03
1
1
@HeavyWave: What you said needs clarification. It's true that functions that create closures are more prone to memory leaks (if you're not careful) and even if not causing a memory leak, they use more memory than they need (because you don't really usually need all the variables in the closure). However, naming a function does not mean you're avoiding the closure. Using a global named function does. But who wants write a serious js app with a bunch of global functions? It's OK for web page enhancement. In that case, though, memory is not much of a concern.
– Juan Mendes
Apr 2 '10 at 15:27
@HeavyWave: What you said needs clarification. It's true that functions that create closures are more prone to memory leaks (if you're not careful) and even if not causing a memory leak, they use more memory than they need (because you don't really usually need all the variables in the closure). However, naming a function does not mean you're avoiding the closure. Using a global named function does. But who wants write a serious js app with a bunch of global functions? It's OK for web page enhancement. In that case, though, memory is not much of a concern.
– Juan Mendes
Apr 2 '10 at 15:27
@Juan Mendes, you are totally right. I should have clarified what I meant. Of course, simply naming a function does not guarantee there will be no leaks. I just wanted to point out that abuse of anonymous functions can lead to serious memory leakage issues, which can be crucial for web applications.
– Egor Pavlikhin
Apr 2 '10 at 16:10
@Juan Mendes, you are totally right. I should have clarified what I meant. Of course, simply naming a function does not guarantee there will be no leaks. I just wanted to point out that abuse of anonymous functions can lead to serious memory leakage issues, which can be crucial for web applications.
– Egor Pavlikhin
Apr 2 '10 at 16:10
1
1
@Egor, there is absolutely nothing about anonymous functions (unnamed function expressions) that will lead to more memory leaks than named function statements. Those "leaks" are caused by closures that never leave scope and will or will not happen based on where the function is declared and the way the function is used, not the type of function you use.
– Prestaul
Jan 6 '12 at 23:04
@Egor, there is absolutely nothing about anonymous functions (unnamed function expressions) that will lead to more memory leaks than named function statements. Those "leaks" are caused by closures that never leave scope and will or will not happen based on where the function is declared and the way the function is used, not the type of function you use.
– Prestaul
Jan 6 '12 at 23:04
@Juan, all functions create closures! What matters is whether or not the references to those functions go out of scope properly allowing those closures to be garbage collected and that has little to do with whether you use an expression or not.
– Prestaul
Jan 7 '12 at 0:09
@Juan, all functions create closures! What matters is whether or not the references to those functions go out of scope properly allowing those closures to be garbage collected and that has little to do with whether you use an expression or not.
– Prestaul
Jan 7 '12 at 0:09
|
show 6 more comments
I suggest a full duel between opposing team members to settle such arguments.
More seriously, in the end it just doesn't matter. The first form (non-named functions) tends to get unwieldy with larger functions, but isn't a big deal at all with small (1-2 line) functions. The second form is similarly harmless.
Any argument against either style is pure bikeshedding, imo.
2
+1 for combining a duel, a good answer and bike shed :) That's also how we got general approval here: by limiting inline function to a few lines.
– Danny T.
Mar 29 '10 at 15:47
+1 for the "full duel" comment. -1 for the bikeshedding comment. There is actually a very significant (read: non-trivial) difference between the two forms, even without reuse.
– T.J. Crowder
Mar 29 '10 at 15:48
1
@TJ Crowder - Sure, there are significant differences. My assumption was that the differences weren't really relevant to their debate (ie, both forms function similarly well in the case they are discussing, and some devs are just arguing based on style (even if they say otherwise)). But you're right "Any argument" is an exhaggeration. :)
– jsight
Mar 30 '10 at 13:38
Thanks for the bikeshedding link, somehow had not seen that before.
– Brian Moeskau
Mar 31 '10 at 3:08
add a comment |
I suggest a full duel between opposing team members to settle such arguments.
More seriously, in the end it just doesn't matter. The first form (non-named functions) tends to get unwieldy with larger functions, but isn't a big deal at all with small (1-2 line) functions. The second form is similarly harmless.
Any argument against either style is pure bikeshedding, imo.
2
+1 for combining a duel, a good answer and bike shed :) That's also how we got general approval here: by limiting inline function to a few lines.
– Danny T.
Mar 29 '10 at 15:47
+1 for the "full duel" comment. -1 for the bikeshedding comment. There is actually a very significant (read: non-trivial) difference between the two forms, even without reuse.
– T.J. Crowder
Mar 29 '10 at 15:48
1
@TJ Crowder - Sure, there are significant differences. My assumption was that the differences weren't really relevant to their debate (ie, both forms function similarly well in the case they are discussing, and some devs are just arguing based on style (even if they say otherwise)). But you're right "Any argument" is an exhaggeration. :)
– jsight
Mar 30 '10 at 13:38
Thanks for the bikeshedding link, somehow had not seen that before.
– Brian Moeskau
Mar 31 '10 at 3:08
add a comment |
I suggest a full duel between opposing team members to settle such arguments.
More seriously, in the end it just doesn't matter. The first form (non-named functions) tends to get unwieldy with larger functions, but isn't a big deal at all with small (1-2 line) functions. The second form is similarly harmless.
Any argument against either style is pure bikeshedding, imo.
I suggest a full duel between opposing team members to settle such arguments.
More seriously, in the end it just doesn't matter. The first form (non-named functions) tends to get unwieldy with larger functions, but isn't a big deal at all with small (1-2 line) functions. The second form is similarly harmless.
Any argument against either style is pure bikeshedding, imo.
answered Mar 29 '10 at 15:42
jsightjsight
21.7k21 gold badges101 silver badges137 bronze badges
21.7k21 gold badges101 silver badges137 bronze badges
2
+1 for combining a duel, a good answer and bike shed :) That's also how we got general approval here: by limiting inline function to a few lines.
– Danny T.
Mar 29 '10 at 15:47
+1 for the "full duel" comment. -1 for the bikeshedding comment. There is actually a very significant (read: non-trivial) difference between the two forms, even without reuse.
– T.J. Crowder
Mar 29 '10 at 15:48
1
@TJ Crowder - Sure, there are significant differences. My assumption was that the differences weren't really relevant to their debate (ie, both forms function similarly well in the case they are discussing, and some devs are just arguing based on style (even if they say otherwise)). But you're right "Any argument" is an exhaggeration. :)
– jsight
Mar 30 '10 at 13:38
Thanks for the bikeshedding link, somehow had not seen that before.
– Brian Moeskau
Mar 31 '10 at 3:08
add a comment |
2
+1 for combining a duel, a good answer and bike shed :) That's also how we got general approval here: by limiting inline function to a few lines.
– Danny T.
Mar 29 '10 at 15:47
+1 for the "full duel" comment. -1 for the bikeshedding comment. There is actually a very significant (read: non-trivial) difference between the two forms, even without reuse.
– T.J. Crowder
Mar 29 '10 at 15:48
1
@TJ Crowder - Sure, there are significant differences. My assumption was that the differences weren't really relevant to their debate (ie, both forms function similarly well in the case they are discussing, and some devs are just arguing based on style (even if they say otherwise)). But you're right "Any argument" is an exhaggeration. :)
– jsight
Mar 30 '10 at 13:38
Thanks for the bikeshedding link, somehow had not seen that before.
– Brian Moeskau
Mar 31 '10 at 3:08
2
2
+1 for combining a duel, a good answer and bike shed :) That's also how we got general approval here: by limiting inline function to a few lines.
– Danny T.
Mar 29 '10 at 15:47
+1 for combining a duel, a good answer and bike shed :) That's also how we got general approval here: by limiting inline function to a few lines.
– Danny T.
Mar 29 '10 at 15:47
+1 for the "full duel" comment. -1 for the bikeshedding comment. There is actually a very significant (read: non-trivial) difference between the two forms, even without reuse.
– T.J. Crowder
Mar 29 '10 at 15:48
+1 for the "full duel" comment. -1 for the bikeshedding comment. There is actually a very significant (read: non-trivial) difference between the two forms, even without reuse.
– T.J. Crowder
Mar 29 '10 at 15:48
1
1
@TJ Crowder - Sure, there are significant differences. My assumption was that the differences weren't really relevant to their debate (ie, both forms function similarly well in the case they are discussing, and some devs are just arguing based on style (even if they say otherwise)). But you're right "Any argument" is an exhaggeration. :)
– jsight
Mar 30 '10 at 13:38
@TJ Crowder - Sure, there are significant differences. My assumption was that the differences weren't really relevant to their debate (ie, both forms function similarly well in the case they are discussing, and some devs are just arguing based on style (even if they say otherwise)). But you're right "Any argument" is an exhaggeration. :)
– jsight
Mar 30 '10 at 13:38
Thanks for the bikeshedding link, somehow had not seen that before.
– Brian Moeskau
Mar 31 '10 at 3:08
Thanks for the bikeshedding link, somehow had not seen that before.
– Brian Moeskau
Mar 31 '10 at 3:08
add a comment |
An inline function avoids namespace pollution and predefined functions have higher reuse. I think you could make cases where each is appropriate.
In his example, there is basically no namespace pollution in either case. He has the whole thing wrapped in a scoping function, thereby creating a well-defined, contained namespace for the named function. No global is created.
– T.J. Crowder
Mar 29 '10 at 15:49
@T.J. True, but taking his example literally, there is nothing to debug in a call stack either and no information needed from the tools. ;)
– Mark
Mar 29 '10 at 16:29
We have no idea what complex logic is going to be where/*code*/is! :-) It may well call a function which calls another function which calls (etc., etc.), and he may well need to debug that. (Or it may just set the document title to "Foo!" which seems unlikely to need debugging.)
– T.J. Crowder
Mar 29 '10 at 16:32
@TJ: I know. :) I was more just trying to point out there are assumption made in all the answers. One being the code in/*code*/is non-trivial, and one that there is more enclosed in the scoping function than included in the example.
– Mark
Mar 29 '10 at 16:39
Ennh, okay. :-) But I will just point out that in the one case he did actually say (effectively) "There's code here." But still, as you say, assumptions.
– T.J. Crowder
Mar 29 '10 at 16:43
add a comment |
An inline function avoids namespace pollution and predefined functions have higher reuse. I think you could make cases where each is appropriate.
In his example, there is basically no namespace pollution in either case. He has the whole thing wrapped in a scoping function, thereby creating a well-defined, contained namespace for the named function. No global is created.
– T.J. Crowder
Mar 29 '10 at 15:49
@T.J. True, but taking his example literally, there is nothing to debug in a call stack either and no information needed from the tools. ;)
– Mark
Mar 29 '10 at 16:29
We have no idea what complex logic is going to be where/*code*/is! :-) It may well call a function which calls another function which calls (etc., etc.), and he may well need to debug that. (Or it may just set the document title to "Foo!" which seems unlikely to need debugging.)
– T.J. Crowder
Mar 29 '10 at 16:32
@TJ: I know. :) I was more just trying to point out there are assumption made in all the answers. One being the code in/*code*/is non-trivial, and one that there is more enclosed in the scoping function than included in the example.
– Mark
Mar 29 '10 at 16:39
Ennh, okay. :-) But I will just point out that in the one case he did actually say (effectively) "There's code here." But still, as you say, assumptions.
– T.J. Crowder
Mar 29 '10 at 16:43
add a comment |
An inline function avoids namespace pollution and predefined functions have higher reuse. I think you could make cases where each is appropriate.
An inline function avoids namespace pollution and predefined functions have higher reuse. I think you could make cases where each is appropriate.
answered Mar 29 '10 at 15:45
MarkMark
8,4216 gold badges32 silver badges39 bronze badges
8,4216 gold badges32 silver badges39 bronze badges
In his example, there is basically no namespace pollution in either case. He has the whole thing wrapped in a scoping function, thereby creating a well-defined, contained namespace for the named function. No global is created.
– T.J. Crowder
Mar 29 '10 at 15:49
@T.J. True, but taking his example literally, there is nothing to debug in a call stack either and no information needed from the tools. ;)
– Mark
Mar 29 '10 at 16:29
We have no idea what complex logic is going to be where/*code*/is! :-) It may well call a function which calls another function which calls (etc., etc.), and he may well need to debug that. (Or it may just set the document title to "Foo!" which seems unlikely to need debugging.)
– T.J. Crowder
Mar 29 '10 at 16:32
@TJ: I know. :) I was more just trying to point out there are assumption made in all the answers. One being the code in/*code*/is non-trivial, and one that there is more enclosed in the scoping function than included in the example.
– Mark
Mar 29 '10 at 16:39
Ennh, okay. :-) But I will just point out that in the one case he did actually say (effectively) "There's code here." But still, as you say, assumptions.
– T.J. Crowder
Mar 29 '10 at 16:43
add a comment |
In his example, there is basically no namespace pollution in either case. He has the whole thing wrapped in a scoping function, thereby creating a well-defined, contained namespace for the named function. No global is created.
– T.J. Crowder
Mar 29 '10 at 15:49
@T.J. True, but taking his example literally, there is nothing to debug in a call stack either and no information needed from the tools. ;)
– Mark
Mar 29 '10 at 16:29
We have no idea what complex logic is going to be where/*code*/is! :-) It may well call a function which calls another function which calls (etc., etc.), and he may well need to debug that. (Or it may just set the document title to "Foo!" which seems unlikely to need debugging.)
– T.J. Crowder
Mar 29 '10 at 16:32
@TJ: I know. :) I was more just trying to point out there are assumption made in all the answers. One being the code in/*code*/is non-trivial, and one that there is more enclosed in the scoping function than included in the example.
– Mark
Mar 29 '10 at 16:39
Ennh, okay. :-) But I will just point out that in the one case he did actually say (effectively) "There's code here." But still, as you say, assumptions.
– T.J. Crowder
Mar 29 '10 at 16:43
In his example, there is basically no namespace pollution in either case. He has the whole thing wrapped in a scoping function, thereby creating a well-defined, contained namespace for the named function. No global is created.
– T.J. Crowder
Mar 29 '10 at 15:49
In his example, there is basically no namespace pollution in either case. He has the whole thing wrapped in a scoping function, thereby creating a well-defined, contained namespace for the named function. No global is created.
– T.J. Crowder
Mar 29 '10 at 15:49
@T.J. True, but taking his example literally, there is nothing to debug in a call stack either and no information needed from the tools. ;)
– Mark
Mar 29 '10 at 16:29
@T.J. True, but taking his example literally, there is nothing to debug in a call stack either and no information needed from the tools. ;)
– Mark
Mar 29 '10 at 16:29
We have no idea what complex logic is going to be where
/*code*/ is! :-) It may well call a function which calls another function which calls (etc., etc.), and he may well need to debug that. (Or it may just set the document title to "Foo!" which seems unlikely to need debugging.)– T.J. Crowder
Mar 29 '10 at 16:32
We have no idea what complex logic is going to be where
/*code*/ is! :-) It may well call a function which calls another function which calls (etc., etc.), and he may well need to debug that. (Or it may just set the document title to "Foo!" which seems unlikely to need debugging.)– T.J. Crowder
Mar 29 '10 at 16:32
@TJ: I know. :) I was more just trying to point out there are assumption made in all the answers. One being the code in
/*code*/ is non-trivial, and one that there is more enclosed in the scoping function than included in the example.– Mark
Mar 29 '10 at 16:39
@TJ: I know. :) I was more just trying to point out there are assumption made in all the answers. One being the code in
/*code*/ is non-trivial, and one that there is more enclosed in the scoping function than included in the example.– Mark
Mar 29 '10 at 16:39
Ennh, okay. :-) But I will just point out that in the one case he did actually say (effectively) "There's code here." But still, as you say, assumptions.
– T.J. Crowder
Mar 29 '10 at 16:43
Ennh, okay. :-) But I will just point out that in the one case he did actually say (effectively) "There's code here." But still, as you say, assumptions.
– T.J. Crowder
Mar 29 '10 at 16:43
add a comment |
I think that the only difference in a code like that is that with the second piece of code you can re-call the same function (sometimes with "timer functions" it's useful):
(function()
function invokeMe()
if(..) setTimeout(invokeMe, 5);
setTimeout(invokeMe, 5);
)();
note that you can also do this witharguments.callee.
– Pointy
Mar 29 '10 at 15:49
1
@Pointy: True -- at a serious performance cost in nearly all implementations (we're talking orders of magnitude here), and not in the new "strict" mode.
– T.J. Crowder
Mar 29 '10 at 15:53
@TJ wow thanks, that's good to know
– Pointy
Mar 29 '10 at 16:11
@Pointy: Yeah, I was really shocked when I learned about the performance aspect.
– T.J. Crowder
Mar 29 '10 at 16:33
@TJ I'm guessing you've seen the stuff about IE w.r.t. named functions used as rvalues yura.thinkweb2.com/named-function-expressions still that's a really good article
– Pointy
Mar 29 '10 at 16:36
|
show 2 more comments
I think that the only difference in a code like that is that with the second piece of code you can re-call the same function (sometimes with "timer functions" it's useful):
(function()
function invokeMe()
if(..) setTimeout(invokeMe, 5);
setTimeout(invokeMe, 5);
)();
note that you can also do this witharguments.callee.
– Pointy
Mar 29 '10 at 15:49
1
@Pointy: True -- at a serious performance cost in nearly all implementations (we're talking orders of magnitude here), and not in the new "strict" mode.
– T.J. Crowder
Mar 29 '10 at 15:53
@TJ wow thanks, that's good to know
– Pointy
Mar 29 '10 at 16:11
@Pointy: Yeah, I was really shocked when I learned about the performance aspect.
– T.J. Crowder
Mar 29 '10 at 16:33
@TJ I'm guessing you've seen the stuff about IE w.r.t. named functions used as rvalues yura.thinkweb2.com/named-function-expressions still that's a really good article
– Pointy
Mar 29 '10 at 16:36
|
show 2 more comments
I think that the only difference in a code like that is that with the second piece of code you can re-call the same function (sometimes with "timer functions" it's useful):
(function()
function invokeMe()
if(..) setTimeout(invokeMe, 5);
setTimeout(invokeMe, 5);
)();
I think that the only difference in a code like that is that with the second piece of code you can re-call the same function (sometimes with "timer functions" it's useful):
(function()
function invokeMe()
if(..) setTimeout(invokeMe, 5);
setTimeout(invokeMe, 5);
)();
answered Mar 29 '10 at 15:43
mck89mck89
13.6k15 gold badges72 silver badges98 bronze badges
13.6k15 gold badges72 silver badges98 bronze badges
note that you can also do this witharguments.callee.
– Pointy
Mar 29 '10 at 15:49
1
@Pointy: True -- at a serious performance cost in nearly all implementations (we're talking orders of magnitude here), and not in the new "strict" mode.
– T.J. Crowder
Mar 29 '10 at 15:53
@TJ wow thanks, that's good to know
– Pointy
Mar 29 '10 at 16:11
@Pointy: Yeah, I was really shocked when I learned about the performance aspect.
– T.J. Crowder
Mar 29 '10 at 16:33
@TJ I'm guessing you've seen the stuff about IE w.r.t. named functions used as rvalues yura.thinkweb2.com/named-function-expressions still that's a really good article
– Pointy
Mar 29 '10 at 16:36
|
show 2 more comments
note that you can also do this witharguments.callee.
– Pointy
Mar 29 '10 at 15:49
1
@Pointy: True -- at a serious performance cost in nearly all implementations (we're talking orders of magnitude here), and not in the new "strict" mode.
– T.J. Crowder
Mar 29 '10 at 15:53
@TJ wow thanks, that's good to know
– Pointy
Mar 29 '10 at 16:11
@Pointy: Yeah, I was really shocked when I learned about the performance aspect.
– T.J. Crowder
Mar 29 '10 at 16:33
@TJ I'm guessing you've seen the stuff about IE w.r.t. named functions used as rvalues yura.thinkweb2.com/named-function-expressions still that's a really good article
– Pointy
Mar 29 '10 at 16:36
note that you can also do this with
arguments.callee.– Pointy
Mar 29 '10 at 15:49
note that you can also do this with
arguments.callee.– Pointy
Mar 29 '10 at 15:49
1
1
@Pointy: True -- at a serious performance cost in nearly all implementations (we're talking orders of magnitude here), and not in the new "strict" mode.
– T.J. Crowder
Mar 29 '10 at 15:53
@Pointy: True -- at a serious performance cost in nearly all implementations (we're talking orders of magnitude here), and not in the new "strict" mode.
– T.J. Crowder
Mar 29 '10 at 15:53
@TJ wow thanks, that's good to know
– Pointy
Mar 29 '10 at 16:11
@TJ wow thanks, that's good to know
– Pointy
Mar 29 '10 at 16:11
@Pointy: Yeah, I was really shocked when I learned about the performance aspect.
– T.J. Crowder
Mar 29 '10 at 16:33
@Pointy: Yeah, I was really shocked when I learned about the performance aspect.
– T.J. Crowder
Mar 29 '10 at 16:33
@TJ I'm guessing you've seen the stuff about IE w.r.t. named functions used as rvalues yura.thinkweb2.com/named-function-expressions still that's a really good article
– Pointy
Mar 29 '10 at 16:36
@TJ I'm guessing you've seen the stuff about IE w.r.t. named functions used as rvalues yura.thinkweb2.com/named-function-expressions still that's a really good article
– Pointy
Mar 29 '10 at 16:36
|
show 2 more comments
Can't we all just get along?
(function()
setTimeout( (function InvokeMe() /*some code here*/ ), 5);
)();
Only one thing really matters, IMO and that's ease of debug. A lot of step tracers won't be able to tell you anything about the func other than the fact that it was anonymous and had args but you can still define inline with a name by putting the definition in parens to force evaluation. For very simple or obvious breaking funcs, I suppose it's not a big deal but to me it's like semis. I really don't care what the other guy does if it doesn't cause pain but I try to always name my funcs because it's not hard and it can be an advantage.
add a comment |
Can't we all just get along?
(function()
setTimeout( (function InvokeMe() /*some code here*/ ), 5);
)();
Only one thing really matters, IMO and that's ease of debug. A lot of step tracers won't be able to tell you anything about the func other than the fact that it was anonymous and had args but you can still define inline with a name by putting the definition in parens to force evaluation. For very simple or obvious breaking funcs, I suppose it's not a big deal but to me it's like semis. I really don't care what the other guy does if it doesn't cause pain but I try to always name my funcs because it's not hard and it can be an advantage.
add a comment |
Can't we all just get along?
(function()
setTimeout( (function InvokeMe() /*some code here*/ ), 5);
)();
Only one thing really matters, IMO and that's ease of debug. A lot of step tracers won't be able to tell you anything about the func other than the fact that it was anonymous and had args but you can still define inline with a name by putting the definition in parens to force evaluation. For very simple or obvious breaking funcs, I suppose it's not a big deal but to me it's like semis. I really don't care what the other guy does if it doesn't cause pain but I try to always name my funcs because it's not hard and it can be an advantage.
Can't we all just get along?
(function()
setTimeout( (function InvokeMe() /*some code here*/ ), 5);
)();
Only one thing really matters, IMO and that's ease of debug. A lot of step tracers won't be able to tell you anything about the func other than the fact that it was anonymous and had args but you can still define inline with a name by putting the definition in parens to force evaluation. For very simple or obvious breaking funcs, I suppose it's not a big deal but to me it's like semis. I really don't care what the other guy does if it doesn't cause pain but I try to always name my funcs because it's not hard and it can be an advantage.
answered Apr 2 '14 at 21:15
Erik ReppenErik Reppen
3,97718 silver badges23 bronze badges
3,97718 silver badges23 bronze badges
add a comment |
add a comment |
I know, that this is an old question,
but to me there is an even more important difference than the ones already mentioned.
hoisting
Every function has to be created and therefore reserves some space in memory and eventually has to be GC later.
Named functions get hoisted to the beginning of the surrounding function, and are therefore created on every function call, wether they get used or not.
Anonymous functions get created only if the code that defines them is executed.
//an example where you wold prefer to use an anonymous function.
//you can assign this (anonymous) function to a variable, so you get your "name" back.
function someFn()
if(condition)
//the variable declaration has been hoisted,
//but the function is created at this point, and only if necessary.
var process = function(value)/* */;
switch(condition2)
case 1: process(valueFor1); break;
case 2: process(valueFor2); break;
/* ... */
function someFn()
var process;
if(condition)
process = function(value) /* A */
else
process = function(value) /* B */
//beware, depending on your code, "process" may be undefined or not a function
process(someValue);
//an example where you would prefer (/ utilize) the hoisting.
function someFn()
/* some code */
while(condition)
//some might want to keep the function definition near the code where it is used,
//but unlike an anonymous function or a lambda-expression this process-function
//is created only once per function-call, not once per iteration.
function process(value, index) /* ... */
/* ... */
process(value, index)
so, as a rule of thumb:
inside a loop there should be no anonymous function or lambda-expression
if you need the function only inside of a (rarely true) condition you should prefer anonymous functions over named ones, since they are only created when needed
if you know your buisness (JavaScript), you know when to ignore this advice
add a comment |
I know, that this is an old question,
but to me there is an even more important difference than the ones already mentioned.
hoisting
Every function has to be created and therefore reserves some space in memory and eventually has to be GC later.
Named functions get hoisted to the beginning of the surrounding function, and are therefore created on every function call, wether they get used or not.
Anonymous functions get created only if the code that defines them is executed.
//an example where you wold prefer to use an anonymous function.
//you can assign this (anonymous) function to a variable, so you get your "name" back.
function someFn()
if(condition)
//the variable declaration has been hoisted,
//but the function is created at this point, and only if necessary.
var process = function(value)/* */;
switch(condition2)
case 1: process(valueFor1); break;
case 2: process(valueFor2); break;
/* ... */
function someFn()
var process;
if(condition)
process = function(value) /* A */
else
process = function(value) /* B */
//beware, depending on your code, "process" may be undefined or not a function
process(someValue);
//an example where you would prefer (/ utilize) the hoisting.
function someFn()
/* some code */
while(condition)
//some might want to keep the function definition near the code where it is used,
//but unlike an anonymous function or a lambda-expression this process-function
//is created only once per function-call, not once per iteration.
function process(value, index) /* ... */
/* ... */
process(value, index)
so, as a rule of thumb:
inside a loop there should be no anonymous function or lambda-expression
if you need the function only inside of a (rarely true) condition you should prefer anonymous functions over named ones, since they are only created when needed
if you know your buisness (JavaScript), you know when to ignore this advice
add a comment |
I know, that this is an old question,
but to me there is an even more important difference than the ones already mentioned.
hoisting
Every function has to be created and therefore reserves some space in memory and eventually has to be GC later.
Named functions get hoisted to the beginning of the surrounding function, and are therefore created on every function call, wether they get used or not.
Anonymous functions get created only if the code that defines them is executed.
//an example where you wold prefer to use an anonymous function.
//you can assign this (anonymous) function to a variable, so you get your "name" back.
function someFn()
if(condition)
//the variable declaration has been hoisted,
//but the function is created at this point, and only if necessary.
var process = function(value)/* */;
switch(condition2)
case 1: process(valueFor1); break;
case 2: process(valueFor2); break;
/* ... */
function someFn()
var process;
if(condition)
process = function(value) /* A */
else
process = function(value) /* B */
//beware, depending on your code, "process" may be undefined or not a function
process(someValue);
//an example where you would prefer (/ utilize) the hoisting.
function someFn()
/* some code */
while(condition)
//some might want to keep the function definition near the code where it is used,
//but unlike an anonymous function or a lambda-expression this process-function
//is created only once per function-call, not once per iteration.
function process(value, index) /* ... */
/* ... */
process(value, index)
so, as a rule of thumb:
inside a loop there should be no anonymous function or lambda-expression
if you need the function only inside of a (rarely true) condition you should prefer anonymous functions over named ones, since they are only created when needed
if you know your buisness (JavaScript), you know when to ignore this advice
I know, that this is an old question,
but to me there is an even more important difference than the ones already mentioned.
hoisting
Every function has to be created and therefore reserves some space in memory and eventually has to be GC later.
Named functions get hoisted to the beginning of the surrounding function, and are therefore created on every function call, wether they get used or not.
Anonymous functions get created only if the code that defines them is executed.
//an example where you wold prefer to use an anonymous function.
//you can assign this (anonymous) function to a variable, so you get your "name" back.
function someFn()
if(condition)
//the variable declaration has been hoisted,
//but the function is created at this point, and only if necessary.
var process = function(value)/* */;
switch(condition2)
case 1: process(valueFor1); break;
case 2: process(valueFor2); break;
/* ... */
function someFn()
var process;
if(condition)
process = function(value) /* A */
else
process = function(value) /* B */
//beware, depending on your code, "process" may be undefined or not a function
process(someValue);
//an example where you would prefer (/ utilize) the hoisting.
function someFn()
/* some code */
while(condition)
//some might want to keep the function definition near the code where it is used,
//but unlike an anonymous function or a lambda-expression this process-function
//is created only once per function-call, not once per iteration.
function process(value, index) /* ... */
/* ... */
process(value, index)
so, as a rule of thumb:
inside a loop there should be no anonymous function or lambda-expression
if you need the function only inside of a (rarely true) condition you should prefer anonymous functions over named ones, since they are only created when needed
if you know your buisness (JavaScript), you know when to ignore this advice
answered Oct 11 '15 at 9:48
ThomasThomas
2,8151 gold badge6 silver badges8 bronze badges
2,8151 gold badge6 silver badges8 bronze badges
add a comment |
add a comment |
The predefined named functions can reduce the JavaScript callback hell issue, which is mentioned at http://callbackhell.com/
add a comment |
The predefined named functions can reduce the JavaScript callback hell issue, which is mentioned at http://callbackhell.com/
add a comment |
The predefined named functions can reduce the JavaScript callback hell issue, which is mentioned at http://callbackhell.com/
The predefined named functions can reduce the JavaScript callback hell issue, which is mentioned at http://callbackhell.com/
answered Nov 13 '16 at 12:02
Alireza FattahiAlireza Fattahi
23.8k8 gold badges72 silver badges113 bronze badges
23.8k8 gold badges72 silver badges113 bronze badges
add a comment |
add a comment |
There are no technical reasons to prefer one version over the other. For me is usually depends on two things:
- I want to resuse the passed callback in another context. In this case I define the function standalone and pass the reference.
- The callback is larger than ~10 lines of code and the function expects additional arguments after the callback. In this case it is hard to reconstruct, which values are actually passed to the function.
Example:
setTimeout(function() // I need to scroll to see the other arguments
// many lines of code
, 0); // <- where does this '0' belong to?
1
Are there still editors which do not show matching parenthesis?
– ceving
Nov 18 '11 at 17:48
add a comment |
There are no technical reasons to prefer one version over the other. For me is usually depends on two things:
- I want to resuse the passed callback in another context. In this case I define the function standalone and pass the reference.
- The callback is larger than ~10 lines of code and the function expects additional arguments after the callback. In this case it is hard to reconstruct, which values are actually passed to the function.
Example:
setTimeout(function() // I need to scroll to see the other arguments
// many lines of code
, 0); // <- where does this '0' belong to?
1
Are there still editors which do not show matching parenthesis?
– ceving
Nov 18 '11 at 17:48
add a comment |
There are no technical reasons to prefer one version over the other. For me is usually depends on two things:
- I want to resuse the passed callback in another context. In this case I define the function standalone and pass the reference.
- The callback is larger than ~10 lines of code and the function expects additional arguments after the callback. In this case it is hard to reconstruct, which values are actually passed to the function.
Example:
setTimeout(function() // I need to scroll to see the other arguments
// many lines of code
, 0); // <- where does this '0' belong to?
There are no technical reasons to prefer one version over the other. For me is usually depends on two things:
- I want to resuse the passed callback in another context. In this case I define the function standalone and pass the reference.
- The callback is larger than ~10 lines of code and the function expects additional arguments after the callback. In this case it is hard to reconstruct, which values are actually passed to the function.
Example:
setTimeout(function() // I need to scroll to see the other arguments
// many lines of code
, 0); // <- where does this '0' belong to?
answered Mar 29 '10 at 15:41
Fabian JakobsFabian Jakobs
16.8k5 gold badges35 silver badges36 bronze badges
16.8k5 gold badges35 silver badges36 bronze badges
1
Are there still editors which do not show matching parenthesis?
– ceving
Nov 18 '11 at 17:48
add a comment |
1
Are there still editors which do not show matching parenthesis?
– ceving
Nov 18 '11 at 17:48
1
1
Are there still editors which do not show matching parenthesis?
– ceving
Nov 18 '11 at 17:48
Are there still editors which do not show matching parenthesis?
– ceving
Nov 18 '11 at 17:48
add a comment |
I prefer to use named functions. Named functions show by name on all debuggers (air, firebug, IE).
Example:
Notice that you can also have inline named functions like
method: function obj_method()
This way, when you look at the stack trace, you'll see function obj_method instead of anonymous.
Were you asking about when to inline a function rather than declare it? When it makes sense in the code. If you need it from two different places, it can't be inline. Sometimes inline make the code easier to read, sometimes harder.
@Juan: That named function expression (method: function obj_method()) doesn't work in most JavaScript implementations (including IE's JScript). It should work, arguably, but it doesn't. For more, see Juriy Zaytsev's article on NFEs: yura.thinkweb2.com/named-function-expressions (This link is actually in one of the other answers, and also in a comment on another answer.)
– T.J. Crowder
Mar 29 '10 at 22:46
@TJ I read the part about Function names in debuggers. That article explains that there are some quirks, it doesn't say that inline named functions don't work in IE. Most of the quirks can be worked around by making sure you never have two functions with the same name under the same scope. So if you have a block that will decide which function to return just name them accordingly, like addEventIE and addEventStandard and you'll be fine. The article actually says: "What it all boils down to is the fact that named function expressions is the only way to get a truly robust stack inspection."
– Juan Mendes
Apr 2 '10 at 15:21
add a comment |
I prefer to use named functions. Named functions show by name on all debuggers (air, firebug, IE).
Example:
Notice that you can also have inline named functions like
method: function obj_method()
This way, when you look at the stack trace, you'll see function obj_method instead of anonymous.
Were you asking about when to inline a function rather than declare it? When it makes sense in the code. If you need it from two different places, it can't be inline. Sometimes inline make the code easier to read, sometimes harder.
@Juan: That named function expression (method: function obj_method()) doesn't work in most JavaScript implementations (including IE's JScript). It should work, arguably, but it doesn't. For more, see Juriy Zaytsev's article on NFEs: yura.thinkweb2.com/named-function-expressions (This link is actually in one of the other answers, and also in a comment on another answer.)
– T.J. Crowder
Mar 29 '10 at 22:46
@TJ I read the part about Function names in debuggers. That article explains that there are some quirks, it doesn't say that inline named functions don't work in IE. Most of the quirks can be worked around by making sure you never have two functions with the same name under the same scope. So if you have a block that will decide which function to return just name them accordingly, like addEventIE and addEventStandard and you'll be fine. The article actually says: "What it all boils down to is the fact that named function expressions is the only way to get a truly robust stack inspection."
– Juan Mendes
Apr 2 '10 at 15:21
add a comment |
I prefer to use named functions. Named functions show by name on all debuggers (air, firebug, IE).
Example:
Notice that you can also have inline named functions like
method: function obj_method()
This way, when you look at the stack trace, you'll see function obj_method instead of anonymous.
Were you asking about when to inline a function rather than declare it? When it makes sense in the code. If you need it from two different places, it can't be inline. Sometimes inline make the code easier to read, sometimes harder.
I prefer to use named functions. Named functions show by name on all debuggers (air, firebug, IE).
Example:
Notice that you can also have inline named functions like
method: function obj_method()
This way, when you look at the stack trace, you'll see function obj_method instead of anonymous.
Were you asking about when to inline a function rather than declare it? When it makes sense in the code. If you need it from two different places, it can't be inline. Sometimes inline make the code easier to read, sometimes harder.
answered Mar 29 '10 at 17:43
Juan MendesJuan Mendes
70.7k20 gold badges120 silver badges167 bronze badges
70.7k20 gold badges120 silver badges167 bronze badges
@Juan: That named function expression (method: function obj_method()) doesn't work in most JavaScript implementations (including IE's JScript). It should work, arguably, but it doesn't. For more, see Juriy Zaytsev's article on NFEs: yura.thinkweb2.com/named-function-expressions (This link is actually in one of the other answers, and also in a comment on another answer.)
– T.J. Crowder
Mar 29 '10 at 22:46
@TJ I read the part about Function names in debuggers. That article explains that there are some quirks, it doesn't say that inline named functions don't work in IE. Most of the quirks can be worked around by making sure you never have two functions with the same name under the same scope. So if you have a block that will decide which function to return just name them accordingly, like addEventIE and addEventStandard and you'll be fine. The article actually says: "What it all boils down to is the fact that named function expressions is the only way to get a truly robust stack inspection."
– Juan Mendes
Apr 2 '10 at 15:21
add a comment |
@Juan: That named function expression (method: function obj_method()) doesn't work in most JavaScript implementations (including IE's JScript). It should work, arguably, but it doesn't. For more, see Juriy Zaytsev's article on NFEs: yura.thinkweb2.com/named-function-expressions (This link is actually in one of the other answers, and also in a comment on another answer.)
– T.J. Crowder
Mar 29 '10 at 22:46
@TJ I read the part about Function names in debuggers. That article explains that there are some quirks, it doesn't say that inline named functions don't work in IE. Most of the quirks can be worked around by making sure you never have two functions with the same name under the same scope. So if you have a block that will decide which function to return just name them accordingly, like addEventIE and addEventStandard and you'll be fine. The article actually says: "What it all boils down to is the fact that named function expressions is the only way to get a truly robust stack inspection."
– Juan Mendes
Apr 2 '10 at 15:21
@Juan: That named function expression (
method: function obj_method()) doesn't work in most JavaScript implementations (including IE's JScript). It should work, arguably, but it doesn't. For more, see Juriy Zaytsev's article on NFEs: yura.thinkweb2.com/named-function-expressions (This link is actually in one of the other answers, and also in a comment on another answer.)– T.J. Crowder
Mar 29 '10 at 22:46
@Juan: That named function expression (
method: function obj_method()) doesn't work in most JavaScript implementations (including IE's JScript). It should work, arguably, but it doesn't. For more, see Juriy Zaytsev's article on NFEs: yura.thinkweb2.com/named-function-expressions (This link is actually in one of the other answers, and also in a comment on another answer.)– T.J. Crowder
Mar 29 '10 at 22:46
@TJ I read the part about Function names in debuggers. That article explains that there are some quirks, it doesn't say that inline named functions don't work in IE. Most of the quirks can be worked around by making sure you never have two functions with the same name under the same scope. So if you have a block that will decide which function to return just name them accordingly, like addEventIE and addEventStandard and you'll be fine. The article actually says: "What it all boils down to is the fact that named function expressions is the only way to get a truly robust stack inspection."
– Juan Mendes
Apr 2 '10 at 15:21
@TJ I read the part about Function names in debuggers. That article explains that there are some quirks, it doesn't say that inline named functions don't work in IE. Most of the quirks can be worked around by making sure you never have two functions with the same name under the same scope. So if you have a block that will decide which function to return just name them accordingly, like addEventIE and addEventStandard and you'll be fine. The article actually says: "What it all boils down to is the fact that named function expressions is the only way to get a truly robust stack inspection."
– Juan Mendes
Apr 2 '10 at 15:21
add a comment |
I tend towards named functions as well. Anonymous function refs are quick, but should only be used for simple stuff. My rule of thumb is that if the function is more than 2 lines of code, it probably belongs in it's own definition.
This is complicated by most example code making use of Anonymous functions. But the samples are usually very simplistic. The method falls apart as things get more complicated. I've seen function refs nested in function refs as the developer realized that more callbacks were needed in subsequent steps. Instead of this tree based logic, I prefer the organization of isolated functions.
And usually end up happy that I can reuse one of the functions I define later.
One important use of an Anonymous Function is when you need to pass scoped data into your function call, but then I usually just wrap my function into the anonymous function.
Named functions are also absolutely necessary if you ever get into Test Driven Development.
add a comment |
I tend towards named functions as well. Anonymous function refs are quick, but should only be used for simple stuff. My rule of thumb is that if the function is more than 2 lines of code, it probably belongs in it's own definition.
This is complicated by most example code making use of Anonymous functions. But the samples are usually very simplistic. The method falls apart as things get more complicated. I've seen function refs nested in function refs as the developer realized that more callbacks were needed in subsequent steps. Instead of this tree based logic, I prefer the organization of isolated functions.
And usually end up happy that I can reuse one of the functions I define later.
One important use of an Anonymous Function is when you need to pass scoped data into your function call, but then I usually just wrap my function into the anonymous function.
Named functions are also absolutely necessary if you ever get into Test Driven Development.
add a comment |
I tend towards named functions as well. Anonymous function refs are quick, but should only be used for simple stuff. My rule of thumb is that if the function is more than 2 lines of code, it probably belongs in it's own definition.
This is complicated by most example code making use of Anonymous functions. But the samples are usually very simplistic. The method falls apart as things get more complicated. I've seen function refs nested in function refs as the developer realized that more callbacks were needed in subsequent steps. Instead of this tree based logic, I prefer the organization of isolated functions.
And usually end up happy that I can reuse one of the functions I define later.
One important use of an Anonymous Function is when you need to pass scoped data into your function call, but then I usually just wrap my function into the anonymous function.
Named functions are also absolutely necessary if you ever get into Test Driven Development.
I tend towards named functions as well. Anonymous function refs are quick, but should only be used for simple stuff. My rule of thumb is that if the function is more than 2 lines of code, it probably belongs in it's own definition.
This is complicated by most example code making use of Anonymous functions. But the samples are usually very simplistic. The method falls apart as things get more complicated. I've seen function refs nested in function refs as the developer realized that more callbacks were needed in subsequent steps. Instead of this tree based logic, I prefer the organization of isolated functions.
And usually end up happy that I can reuse one of the functions I define later.
One important use of an Anonymous Function is when you need to pass scoped data into your function call, but then I usually just wrap my function into the anonymous function.
Named functions are also absolutely necessary if you ever get into Test Driven Development.
answered Jul 22 '11 at 16:40
Ray WadkinsRay Wadkins
5681 gold badge3 silver badges16 bronze badges
5681 gold badge3 silver badges16 bronze badges
add a comment |
add a comment |
In the example provided, the declaration and use of the function are so close that I think the only difference is readability. I prefer the second example.
add a comment |
In the example provided, the declaration and use of the function are so close that I think the only difference is readability. I prefer the second example.
add a comment |
In the example provided, the declaration and use of the function are so close that I think the only difference is readability. I prefer the second example.
In the example provided, the declaration and use of the function are so close that I think the only difference is readability. I prefer the second example.
edited Nov 16 '12 at 9:14
Peter O.
22.1k9 gold badges60 silver badges71 bronze badges
22.1k9 gold badges60 silver badges71 bronze badges
answered Mar 29 '10 at 15:45
lincolnklincolnk
9,7113 gold badges35 silver badges56 bronze badges
9,7113 gold badges35 silver badges56 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2539205%2fjavascript-inline-functions-vs-predefined-functions%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
8
Nit-picking (and yet not): Both of those are inline functions, and neither is more predefined than the other. The only difference is that one of them is unnamed, the other one is named. It's a significant difference, though. (Good question, btw.)
– T.J. Crowder
Mar 29 '10 at 15:52