5

Following from this discussion:

I have a doubt about function declaration in JavaScript.

By anonymous function declaration I mean something like this (https://en.wikibooks.org/wiki/JavaScript/Anonymous_Functions):

var myFunction = function (fruit){
    alert('I like ' + fruit);
}

and by const I mean this:

const myfunction = (fruit) => alert('I like ' fruit);

Is it faster to use an anonymous function, or use a const? I have read that using const allows for compile optimizations in JavaScript. Is there any reason why I should use one instead of the other?

Is this even relevant?

Community
  • 1
  • 1
Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266
  • 2
    Unless you're creating thousands of functions in a loop, I suspect it won't make the slightest bit of difference. Use whichever one is semantically correct. – James Thorpe Dec 09 '15 at 14:52
  • And I get down-voted because? – Flame_Phoenix Dec 09 '15 at 14:54
  • Because this question can only yield opinionated answers. Micro-optimizations and personal preferences are all you'll get mostly. (I didn't downvote btw) – Sterling Archer Dec 09 '15 at 14:55
  • I had the idea that optimizations were mainly... objective. If you don't like my question, that is fine, but saying it is a dumb a question or poorly constructed one is far from true. – Flame_Phoenix Dec 09 '15 at 14:55
  • 2
    This sort of optimization, even if you determined it were possible, is generally pointless to worry about. The state of affairs - particularly for a language under aggressive development like JavaScript - may change with the next release of the compiler or runtime system. Chasing tiny "optimizations" is not worth a fraction of what similar effort devoted to algorithmic improvements can yield for performance. – Pointy Dec 09 '15 at 15:00
  • 1
    *"By anonymous function declaration I mean something like this:"* That's not an anonymous function. It's a *function declaration*, using the name `myFunction`. (And being a declaration, there's no need for the `;` at the end of it.) – T.J. Crowder Dec 09 '15 at 15:15
  • Ah crap, I am so used to it that I forgot, my bad! I will fix it now! Thanks! – Flame_Phoenix Dec 09 '15 at 15:26
  • Hate to say it, but as of the latest edit, it's a syntax error. The parser will treat that as a function declaration, and declarations must have a name. You'd need to make it an expression (for instance, assign it to something). – T.J. Crowder Dec 09 '15 at 15:40
  • @T.J.Crowder perhaps I am not being clear (once again). I have based myself in this explanation: https://en.wikibooks.org/wiki/JavaScript/Anonymous_Functions I will add the link! – Flame_Phoenix Dec 09 '15 at 15:43
  • @Flame_Phoenix: Example of an anonymous function expression: `something = function() { };` or `someMethod(function() { })` or `something = {property: function() { }}`. If the production in your question appears where a statement (not an expression) is expected, and starts with `function`, it will be a function *declaration*, which requires a name. You can also have named function *expressions*: `something = function foo() { };`. – T.J. Crowder Dec 09 '15 at 15:48
  • Ok, I will add the full snipet for clarification! – Flame_Phoenix Dec 09 '15 at 15:50

1 Answers1

12

Anonymous function VS const function

Presumably you're comparing

var func = function() { };
// or
let func = function() { };

with

const func = function() { };

The primary reason for doing that isn't optimization. It's documenting via code that you never intend to change func, and having the engine protect you from accidentally doing so. (I should also note that as of ES2015, none of those functions is anonymous. They all have the name func, because ES2015 adds rules for assigning names to functions created via "anonymous" function expressions based on context, including a rule for simple assignments like the above.)

But regarding optimization:

As with most JavaScript optimization questions, the answer is: It depends. In theory, using const if you never mean to change the value in func means that the JavaScript engine has the option of optimizing on the assumption that the value will never change. Note that it doesn't exempt the engine from handling the possibility the symbol will be shadowed in a nested scope or similar.

Whether the engine actually does optimize in a meaningful way based on that knowledge the value wont' change will depend on the engine's implementation, and likely will vary from engine to engine.

Whether that makes looking up the function via the constant in order to call it any faster than looking it up via the variable will depend on the engine's implementation, as well.

Whether any absolute difference translates into actual gains in your program will depend on the above, how your program is structured, how frequently you're using the function, how the lookup time compares with what the function is actually doing (e.g., swamping), etc.

It depends. :-)

If you run into a situation where you think the lookup time is causing a real-world problem, profile it and see if it makes a difference.


Re your edit:

By anonymous function declaration I mean something like this:

function myFunction(fruit){
    alert('I like ' + fruit);
};

and by const I mean this:

const myfunction = (fruit) => alert('I like ' fruit);

That first one isn't an anonymous function. (Actually, neither of them is.) It's a function named myFunction, created via a function declaration. (And being a declaration, there's no need for the ; at the end.) Function declarations cannot create anonymous functions,¹ the name is a required part of the declaration.²

That said, it doesn't really matter, as once the function is created (which happens at a different time from the expressions I showed above), it behaves very much like the var func = ... example in terms of how func is resolved, whether you can change func, etc.

Your second example varies from your first in not one, but three important ways:

  1. It assigns the function reference to a constant.

  2. It uses an arrow function, rather than a function function (which for lack of a better term I'm going to call a "simple" function).

  3. Your arrow function version returns the result of calling alert (because you're using a concise body on the arrow function). Your declaration version doesn't.

We've already dealt with any performance aspect of #1. #3 is, I suspect, unlikely to matter.

Re #2 (it being an arrow function): Calling an arrow function requires less work than calling a simple function (in theory). The engine doesn't have to set up the arguments pseudo-object, doesn't have to create a this binding. But if the arrow function uses this, it requires more work to look it up (it's like a variable in the outer scope the function closes over). But again, that's the theory; engines can optimize as long as side-effects are not apparent. For instance, if you don't use arguments in your code, modern engines avoid creating it anyway, even for simple functions. And I'd expect optimization around arrow function usage of this to be pretty good, since the this they see cannot change once the function exists.

So (wait for it): It depends.


¹ "Function declarations cannot create anonymous functions" - There's one thing that seems like an exception that rule, which is that export default function() { /*...*/ }; is a function declaration (yes, really) with no explicit name; the name default is used, though, so it doesn't create an anonymous function.

² "...the name is a required part of the declaration..." Except in the export default example above. That's the one exception.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875