4 ms·
function myFunction(arg1, arg2) {}; // This is OK, but... var myFunction = function(arg1, arg2) {}; // This is best! The second option is better, and
by killahpriest 14y ago
function myFunction(arg1, arg2) {}; // This is OK, but...
var myFunction = function(arg1, arg2) {}; // This is best!
The second option is better, and is properly scoped, but it leads to certain syntax problems once you get into closures.
What problems? How does assigning the function to a variable help avoid needing to make a closure for this?
- jrajav 14y agoThe first one will be hoisted to the top of the function (the whole declaration), the second one won't (the variable will, but not the function expression itself). EDIT: To clarify: All variable declarations in Javascript do indeed get hoisted to the top of the scope, but with function declarations even the function value itself gets hoisted. So for instance, this returns 'two': function foo() { function one() { return 'one'; } return one(); function one() { return 'two'; } } foo(); But this returns 'one': function foo() { var one = function one() { return 'one'; } return one(); var one = function one() { return 'two'; } } foo();
- nadaviv 14y agoNamed functions are generally fine to use (they're hoisted, but otherwise behave the same), but named function expressions (where you both give the function name, and use it as an expression) has some nasty memory leak issues on IE [1]. Some people think its better to ditch named functions completely rather than learn exactly when its problematic and when it's not... which I'm not sure I completely agree with, but its probably a good advice to give to a new JavaScript programmer, as it basically behaves the same minus those issues. CoffeeScript ended up removing named functions [2] [3] (with the exception of being used for "class" declarations, where its known they're safe) for that reason. [1] http://kangax.github.com/nfe/#jscript-memory-management http://kangax.github.com/nfe/#jscript-memory-management [2] https://github.com/jashkenas/coffee-script/issues/366#issuecomment-242134 https://github.com/jashkenas/coffee-script/issues/366#issuec... [3] https://github.com/jashkenas/coffee-script/wiki/FAQ https://github.com/jashkenas/coffee-script/wiki/FAQ - "Q: Is there any way to name functions, for reflection and recursion?" edit: formatting
- jrajav 14y agoThe memory leak issues you're referring to are old and have been fixed. They may be an issue if you are writing code that must support legacy IE, and then only in specific cases. However, if that's not you, then there's no reason not to use named function expressions. There's no other way to completely avoid arguments.callee (which is going away) for recursive reference, and it also makes call stacks and debug messages clearer. You won't think either of those are a real issue until they are. So no, I disagree that that's good advice to give to a new programmer.
- nadaviv 14y agoThe memory leaks issues are effecting IE <= 8, which still has around 10% market share. Losing one of ten potential customers is not acceptable for most businesses. Unless you're writing server-side JavaScript, or have a specific demographic that uses newer technologies, those kind of bugs are not something that you should ignore. To address your other points - you can get a recursive reference by simply assigning your function to a variable, `var f = function(){ f(); }`. There's no need for named functions for that. As for call stacks and debug messages - that was true some time ago, but modern debugging tools can figure out the function name pretty good even if it isn't a named function. I work with CoffeeScript code(who doesn't have named functions) and stack traces are fine. I think its a better practice to avoid named function expressions on client-side code. Non-expression named functions are fine, but considering that named function doesn't actually have any benefit (I don't consider hoisting a benefit - I prefer to have my functions declared before they're used), I can see why some people would decide to just avoid them altogether. edit: spelling
- jrajav 14y ago> To address your other points - you can get a recursive reference by simply assigning your function to a variable, `var f = function(){ f(); }`. There's no need for named functions for that. > (I don't consider hoisting a benefit - I prefer to have my functions declared before they're used) > As for call stacks and debug messages - that was true some time ago, but modern debugging tools can figure out the function name pretty good even if it isn't a named function. All of these ignore the fact that functions are not simply declared once in Javascript and then used later, like in C. It's a dynamic language with first-class functions and function literals. You could assign to a variable in this case, but that's needlessly restricting: asyncFunc(function cb(result) { print(result); }); As for IE and memory leaks, I already acquiesced to the need to support it in some cases. Still, for many people it is acceptable to drop support for IE8 despite its general market share, and this leak may not be an issue if the function in question is not related to repeating code. Certainly you should not ignore the issue.