5 ms·
I 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 PO
by mattmanser 13y ago
I 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 13y 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 13y 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.
- VMG 13y agoThe problems you describe are due to bad runtime environments rather than problems of the language. Don't write JS in that style when compatibility with ancient browsers is not an issue. Hard to read, maintain and understand.
- mattwad 13y agoActually using var makes the function more reusable. For one, having the reference allows you to pass it along to other functions. Further, declaring a function without var is not the same as throwing it into global scope, it can still only be accessed by the local scope *unless you assign it to a global variable of course :)
- hrktb 13y agoYou can pass any function as an object everywhere you want, i.e. function someName(){} still maps to the identifier someName that is scoped where it was declared and can be passed around to other objects and functions. No need to "var someName = function someName..." to do so.
- jameshart 13y agoIt's not using a variable to declare a function, it's using a variable to store a function, maybe only temporarily. The function happens to also be declared on the same line. Would you also object to var functions = { a: function() {}, b: function() {} } or var functions = [ function() {}, function() {} ] ? in those cases we're creating a storage structure and loading it with functions - a single variable is just another case of the same. What about var log = console.log || function(msg) { }; ? The function foo() {} declaration syntax in JavaScript is a syntactic hack that uses function hoisting to allow functions to be used 'before' they are declared. All it does is turn into a var foo = function foo() {} at the top of the current scope. But because of var scope, variables can also be used before they're declared, so often you don't need it anyway: var a = function() { return b(); }; var b = function() {}; a(); I suspect people who strongly prefer var foo = function() {} over function foo() {} are people who have internalized the idea of functions as data. I'd hesitate to say 'functional programmers', but perhaps 'functional JavaScripters' is valid. As for "There are also very good reasons to declare a function within the scope of another too. But they are few and far between" - the benefits of closure over parent function scope are incredibly powerful - I don't think they are few and far between at all. I tend to declare pretty much all my functions inside a function using the module pattern: (function() { var x = 0; var f = function() { return x++; }; window.makeObj = function() { return { id: f() }; } })();
- mattmanser 13y agoIf you're regularly declaring a bunch of anon functions in an array I'd hate to use your code. And your first example is an object declaration, which I have no beef with. The console.log is the rare time I'd probably use it. In the end, if you think normal function declaration is a "syntactic hack" we're simply not going to agree. I've used a fair few different languages and to me the distinction between a plain old function and a closure is a useful distinction that helps me read the code quicker. By declaring it as a variable, you're making it hard to decide which it will be as well. And deeply coupling code for no good reason. This is the other thing I can't understand. I can't even MOVE your function without worrying about side effects. On a side note, my original post is going up and down in votes like a yo-yo.
- windsurfer 13y agoHave you ever worked in a large Javascript codebase? Anonymous functions allow for namespacing. Declare your namespace as var Namespace = {}, and then attach functions as Namespace.foo = function(){}. Typically in a definition file I will have var self = Namespace; and then declare functions as self.foo = function(){}.
- Roboprog 13y agoI'm rather fond of that style, or the variant: projectname = { A_CONSTANT: ..., someFunc: function(...) { }, ... lastFunc: function(...) { } } Basically, JSON layout but with the functions in the resulting namespace. Debugging & diagnostics for this layout in Firefox and Chrome is not a problem. As for IE, well, some things can't be fixed, I guess.
- sopooneo 13y agoI do that a bit, but found it tricky to end everything with a comma, and effectively use ":" instead of "=" for declarations. Lately I've been doing projectname = (function(){ self = {}; self.A_CONSTANT = ...; self.someFunc = function(...){ }; self.lastFunc = function(...){ }; return self; })(); I think that produces the exact same end result, but someone set me straight if I'm mistaken.
- Roboprog 13y agoWhat you do is a bit more complicated, but has the benefit of making your data "private" within a closure. You are using a function as an object, and assigning other functions as fields within its "prototype". I think these inner functions can call each other w/out a prefix, as methods of the same object. My version is the "static method" version that requires the namespace and a dot before any function calls. I'm OK with that, unless I need a bunch of instances of something. P.S. - the semicolons don't really do anything (other than make Doug C feel good), as JS is a line oriented language, and will complete statements when they "look done", semis or not. Think of semicolons in JS like colons in BASIC: they let you put a second statement on the same line.
- ookookook 13y agoI like to extract out non-semantic parts of a function and wrap the main functionality with these parts. So, if I wanted to create a function that could be called in a fluent style I could write : function doSomething() { // do stuff return this; } However, the `return this` line doesn't really have anything to do with the core of what the method is supposed to do. Its largely an implementation detail. I feel the method looks much better like : var doSomething = fluent(function() { // doSomething }); The fluent function handles the `return this;` so it doesn't obscure the core method. It is one of most beautiful aspects of javascript that it enables you to build functions from other functions.
- levlandau 13y agoFor me i find that readability is a good reason to declare functions as vars inside a function. It's much easier to follow (pseudo) code that says function handleCustomers = init some variables, var processCustomer = some function definition, forEach customer-->processCustomer(), do some update to some backend when we're done. It's even more pronounced when there are more blocks of code like processCustomer that are easier to read when pulled into their own function. It's especially useful in node when stringing a bunch of callbacks together.
- longpoke_ 13y ago> I honestly don't understand people who regularly use variables to declare functions I honestly don't understand people who give a fuck.
- twistedpair 13y agoFirst class functions blow many peoples' minds.
- mattmanser 13y ago6 years ago, maybe. Today, no. This is my other beef with ignorant javascript programmers, so stuck in the past. Most other languages now do this, and, shock, horror, do it better than js which is horribly behind the times.