8 ms·
“var functionName” vs “function functionName”
- yiedyie 12y agoBut: functionOne = function() { // Some code }; (i.e. without the var) is represented same as: function functionTwo() { // Some code } is it?
- LunaSea 12y agoNo, with or without the var doesn't change the fact that it is still a variable declaration. Without the "var" keyword, you just created a global variable rather than one restricted to your local scope.
- jaredmcateer 12y agoThe function declaration is still restricted to the scope it's within. The problem is that the function declaration does some additional hoisting magic nothing else gets. If you declare a variable in the middle of a function the variable name gets hoisted but the value does not. If you declare a function in the middle of another function the name gets hoisted but so does the value. This can lead to some additional quirkiness, which is why it's recommended to use the expression assigned ot a variable, to maintain consistency.
- sarink 12y ago+99999
- deleted 12y ago[deleted]
- LunaSea 12y ago> And that's why I hate JavaScript. more like: "And that's why I don't know how to program."
- deleted 12y ago[deleted]
- subbu 12y agoIts called function hoisting. Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- moron4hire 12y agoAlso, the latter syntax names the function for the stack frame, which is useful for debugging. You will sometimes see MyClass.prototype.myFunc = function myFunc_(){}, because otherwise myFunc is only an anonymous function assigned to a property on the prototype object. And the trailing underscore is to placate some version of IE. Or something. I can't keep it all strait when I'm just out of bed.
- thedufer 12y agoThat double-naming thing is going out of fashion, since modern browsers + node.js all know how to figure out function names without it.
- deleted 12y ago[deleted]
- AdrianRossouw 12y agoi know it's sort of side effect driven, but i like function hoisting. it's one of my main tools to fight the callback pyramid of doom. use named functions, place them below the code that uses them. all flat.
- wakaflaka 12y agoYou are just asking for race condition issues with that type of "solution."
- andrey-p 12y agoYou can still pass in callbacks to them. So if I got the parent's intent right, you've got: function bunchOfAsyncThings(callback) { var function1, function2; function1 = function (callback) { // do stuff here, then do callback function2(callback); }; function 2 = function (callback) { // done with everything callback(); }; function1(callback); } (Edit: formatting)
- Jare 12y agoAre you referring to a case like this? { f(); var a = 3; function f() { console.log(a); } } That will print "undefined" because the entire function f() is hoisted and callable in the first line, but the variable a has not yet been assigned the value. That's not a race condition (those are related to timing in concurrent systems) but is certainly the sort of counter-intuitive visibility that makes me prefer to use function expressions most of the time.
- pdpi 12y agohow, exactly, is that going to cause race conditions?
- icebraining 12y agoWhy not do the reverse, and declare the inner functions before?
- 12y ago
- mattmanser 12y agoI honestly don't understand people who regularly use variables to declare functions (with the exceptions of the extremely rare cases it might be useful). My POV is you simply shouldn't be putting a function in a variable, it's supposed to be reusable code and you've just made it's position a completely pointless dependency as well as obfuscated the code's meaning. A named function is clearly supposedly immutable, reusable code (save monkey patching). A function in a variable looks like you might change it. I want to stress, there are very good reasons to assign a function to a variable. There are also very good reasons to declare a function within the scope of another too. But they are few and far between. To willy nilly declare functions like they're variables. Bizarre. Perhaps someone who does it can explain what it gains them? The place I first saw it was in Crockford's the Good Parts, but he seems to have stopped doing it when you go look at his code.
- VMG 12y agoBinding a function to a variable does not make it less reusable. Just like binding other values like numeric constants, strings or objects to variables makes them less reusable. Binding functions to variables however does highlight the fact that functions are first-class values in JavaScript and can be locally scoped, passed to other functions and can be operated on. Functions in Javascript are not the same as functions C or Java and don't need to pretend to be similar. If you want to prevent a function binding to be changed, use es6's const and don't pretend that function declarations helps you with that.
- robert_tweed 12y agoI see two things in lots of JavaScript these days, both of which probably contribute to the perception of JavaScript as a bad language: 1. Anonymous functions assigned to variables. These make debugging a nightmare. Some (possibly all) versions of IE reports something like "error on line 0" when it occurs in such a function, so you really have no idea what went wrong. 2. Accidental closure creation. Both of these are avoided by just declaring your functions statically. If you want to create an object, you can still assign a static function to a property, e.g.: function foo() { ... } Foo.prototype.foo = foo; Back when I used to primarily write JavaScript, and compatibility with things like Netscape and IE3 were a concern, I'd write all my code roughly like that and just namespace the functions if they are for a particular class, e.g.: function className_functionName() { ... } className.prototype.functionName = className_functionName; This guarantees maximum compatibility with very old versions of JavaScript/JScript, runtime efficiency (functions get evaluated at parse time not runtime, also guaranteeing only one copy of the function code is ever created) and no possibility of accidentally creating a closure where you don't want to (which can lead to memory leaks). The downside is that it it makes your JavaScript code look more like C++ code that Java, and even less like Ruby. It also requires a tiny bit more typing, and we all know how much programmers hate typing.
- schrodinger 12y agoOne big difference is that: function functionName() will show up in a stack trace with a name, whereas the other won't. You can also do this: var f = function functionName() { }
- ahoge 12y agohttp://kangax.github.io/nfe/ http://kangax.github.io/nfe/
- jakub_g 12y agoKangax's article is the best and most detailed piece of writing ever on NFEs, including crazy implementation bugs in IE and other old versions of the browsers.
- evilpie 12y agoActually that's not true at least in Firefox and probably chrome. Take a look at http://jsfiddle.net/2LsSg/ http://jsfiddle.net/2LsSg/. window.onload/g@http://fiddle.jshell.net/2LsSg/show/:23:5 window.onload/f@http://fiddle.jshell.net/2LsSg/show/:26:5 @http://fiddle.jshell.net/2LsSg/show/ line 29 > eval:1:1 window.onload@http://fiddle.jshell.net/2LsSg/show/:29:1 (I guess jsfiddle wraps the JS code in a window.onload handler, which makes this a bit more ugly)
- randallsquared 12y agoIt's true in node.js, as of last year, which is where I use the style "var name = function name(){};", because debugging dozens of anonymous functions in node.js' callback playground will ruin your day.
- thedufer 12y agoNot true as of 0.10.24, which is what I have installed.
- badman_ting 12y ago
- badman_ting 12y agoI recommend named functions, because a stack trace 12 deep of all anonymous functions is a real bummer.
- grumblestumble 12y agoI'm 'ardkore and rigidly enforce `var functionName = function functionName() {}`, under threat of flaying.
- grumblestumble 12y agoSeriously though, when binding functions to object properties, the seemingly redundant syntax is worth the cleaner call stack: `this.functionName = function functionName() {}`. Simply named functions in promises can also be helpful : `promiseFn().then(function success() {}, function failure() {}` vs. the more common anonymous inline functions.
- thedufer 12y agoWhat's the goal there? v8, at least, will give the name in a stack trace even if the function is declared like `var a = function(){}`.
- Cthulhu_ 12y agoReally? I'm using Chrome, and at least for me, unfortunately it doesn't. Second, V8 isn't the only JS engine out there, a lot of tools will simply put the function as 'anonymous function' in stack traces.
- thedufer 12y ago> var a = function(){throw Error('err')} undefined > try{a()}catch(err){err.stack} "Error: err at Error (native) at a (<anonymous>:2:26) at <anonymous>:2:5 at Object.InjectedScript._evaluateOn (<anonymous>:641:39) at Object.InjectedScript._evaluateAndWrap (<anonymous>:580:52) at Object.InjectedScript.evaluate (<anonymous>:495:21)" The "at a" is what we're looking for. I develop largely in Chrome; its been doing this for months, at least. It also works in IE11 (the only version I have readily available), Firefox, and Safari.
- yiransheng 12y agoOne pattern I have seen emerging is Object.prototype.method = function Object$method() { ... } an interesting mixture of both method.
- yiransheng 12y agoAn example case where "var" method is useful: function make_dot_product(dim) { if (dim === 3) { var dot = function(a,b) { return a.x*b.x+a.y*b.y+a.z*b.z } } else if (dim === 2) { var dot = function(a,b) { return a.x*b.x+a.y*b.y } } return dot } vs. function make_dot_product(dim) { if (dim === 3) { function dot(a,b) { return a.x*b.x+a.y*b.y+a.z*b.z } } else if (dim === 2) { function dot(a,b) { return a.x*b.x+a.y*b.y } } return dot } The second case is erroneous, as it will always return 2-dimensional dot function (even if you call make_dot_product(20)). The is because function nameSpace() is defined at parse time, so inside the make_dot_product scope, two instance of dot functions are created, with the second overwriting the first. If we use var f = function() {...} this can be avoided.
- gnaritas 12y agoNot really a good case for var function make_dot_product(dim) { if (dim === 3) { return function(a,b) { return a.x*b.x+a.y*b.y+a.z*b.z } } else if (dim === 2) { return function(a,b) { return a.x*b.x+a.y*b.y } } return null; }
- jonahx 12y agoNot a great counterexample imo: function make_dot_product(dim) { return (dim === 3) ? dot3 : dot2; function dot3(a,b) { return a.x*b.x+a.y*b.y+a.z*b.z } function dot2(a,b) { return a.x*b.x+a.y*b.y } }
- Cthulhu_ 12y agoI think I prefer this one, although I'd put the return at the bottom for convention's sake. A lot of people don't know - or want or need to know - about the specifics of hoisting and what-have-you, and will consider this counter-intuitive.
- yawboakye 12y ago
- deleted 12y ago[deleted]
- gopalv 12y agoNeither would be any good, really for better coding. namespace.functionName = function() { } I'm not talking about performance here, but from a sheer maintainability nightmare that JS creates. If you care about this, don't let your functions be unbound. The only reason to store a function in a var is because it is a closure. And in a way, a closure is data encapsulation in a totally non OO way.
- Terr_ 12y ago> namespace.functionName = function() { } I'd rather use Asychronous Module Definitions: http://requirejs.org/docs/whyamd.html http://requirejs.org/docs/whyamd.html
- untog 12y agoIMO there's nothing wrong with declaring functions with a var. It's part and parcel of functions being a first class object in JS, and you being able to pass it around in functions.
- scarmig 12y agoAn additional wrinkle: recursive functions. If you've got a recursive function, you absolutely must use a function declaration to introduce the function identifier. Otherwise you inadvertently create a closure. Consider: var a = function(b) { if (b === 0) { return true; } return a(--b); }; var b = a; a = function() { return false; }; b(5); As an alternative, you should go var a = function a2(b) { if (b === 0) { return true; } return a2(--b); }; var b = a; a = function() { return false; }; var a2 = function() { return false; }; b(5); Perhaps counterintuitively, a2 doesn't leak into the containing scope, which makes it safe to use within the function it declares. Some older browsers fuck this up though, IIRC.
- yawboakye 12y agoyou can use the same name for both the variable and the function in your (alternative) solution. It's better and less confusing. and another reason your alternative is preferred is because arguments.callee is going away (if it isn't gone already) :/
- scarmig 12y agoIndeed. Having separate names was for didactic purposes. In real code, naming the variable the same as the function would be very strongly recommended.
- lotides 12y agoI've been trying to learn to code (I'm a designer) for a while now. I've read books, played around with making things and I'm now taking the JavaScript course on Codecademy. It taught me: var functionName = function() { // whatever } I had no idea there were other ways to write a function. I still don't understand what the benefits or drawbacks are of each method. Maybe I haven't made it that far yet. But I literally have no idea what most of you are talking about in this thread. I feel like I visited a post written in chinese. The scope of learning to code seems overwhelming. Finding small bugs in syntax and design is stressful. What I'm supposed to learn (language, style, syntax, frameworks) seems to change faster than I can learn it. I wish I would have started all of this earlier ... like when I was 10.
- scarmig 12y agoMy advice: don't sweat it. Best thing to do would be to code and build things, and then you'll come back to this article in a year and be like, oh, that's obvious. Abstruse technical details don't matter that much, especially when you're starting out.
- WoodenChair 12y agoI'm currently finishing up writing a programming book for absolute beginners and I couldn't agree more with this advice. Don't sweat it! You don't need to learn all of the details of the latest framework. Get comfortable with some small piece of the landscape, stake your claim, and build something you like with it.
- npinguy 12y agoJavascript is not the easiest first language to pick up, though obviously it is the one you will get the most bang for your buck from as a designer. I think what might help you is thinking of programming languages as foreign languages. They have their own vocabulary and grammar. So right away, let that take the pressure off in terms of how quickly you are picking it up. Some people can pick up foreign languages easily. Others can pick up programming languages just as fast. But even if you don't have a natural knack for it, with some persistence practice and time, you will get there. Also, remember that the person you are talking to in your new language (the computer) is the biggest grammar nazi you have ever met. And they will refuse to acknowledge you unless you use the proper form exactly right. So you can't get away with just memorizing "Could you please tell me where is the bathroom?" because one day you'll accidentally say "Could please tell me bathroom", and your previously helpful foreign friend will completely blow you off. What that means is I think it will be easier if you try to really understand every part of the line you are writing: What is a function. What is "var". WHY do you use var sometimes, and sometimes not, and what is the difference. What is the crazy jQuery syntax all about, with $'s, and parenthesis, and callbacks, etc. It will take you more time up front, but will lead to fewer frustration in the long run. Good luck!
- reconor 12y agoUsing var to declare a variable later assigned to an anonymous function can help with managing larger JavaScript projects where scoping and data member access is important. Here is a pattern I tend to apply rather frequently, included is an example for a custom instance object, which would be created with 'new', and a Namespace object: var MyObject; (function() { var staticPrivateVariable; MyObject = function(opts) { // Do Initialization Stuff }; MyObject.prototype.publicInstanceFunction = function(opts) { // Do instance stuff }; })(); var Namespace; (function() { var staticPrivateVariable; Namespace = function(opts) { // Do Initialization Stuff }; Namespace.publicFunction = function(opts) { }; function privateFunction(opts) { // Do some private stuff } })();
- yawboakye 12y agoThe primary difference is "hoisting" https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe.... Closure can be created in both cases. Also, functions have names. var funcName = function () {}; funcName.name; // "" function func2() {}; func2.name; // "func2" Thus, anynomous functions are truly anonymous whether or not they're assigned to a variable. `func2` can be assigned to a variable too. It'd retain its name (`func2`).
- niix 12y agoAlso hoisting.