16

I have some nested functions such as

var freak = function() {
    var die = function() { ... }
    die(this);
}

As far as I have learned, the die function will get created (allocated) each time freak is called.

So if freak gets called a lot of time, that means a lot of memory will be wasted (assuming die is not using anything from freak's context; in other words, it works fine even if it was allocated only once and shared between multiple calls of freak – this is what I meant with wasted).

Is my understanding correct? And does that mean nested functions should be avoided entirely?

Dr1Ku
  • 2,875
  • 3
  • 47
  • 56
Khanh Nguyen
  • 11,112
  • 10
  • 52
  • 65

1 Answers1

27

As far as I have learned, the die function will get created (allocated) each time freak is called.

Yes. This is true. A new function-object is created.

So if freak gets called a lot of time, that means a lot of memory will be wasted [...]

For some very small and normally inconsequential value of "wasted".

JavaScript engines are very efficient these days and can perform a wide variety of tricks/optimizations.

For instance, only the function-object (but not the actual function code!) needs to be "duplicated" internally.

[...] does that mean nested functions should be avoided entirely?

No. There is no "wasting" problem without an actual test-case that shows otherwise. This idiom (of nested and anonymous functions) is very common in JavaScript and very well-optimized for.

Nested functions provide many benefits including self-documenting code, smaller self-contained lexical scopes, and other code isolation/organization advantages.

Dr1Ku
  • 2,875
  • 3
  • 47
  • 56
user2864740
  • 60,010
  • 15
  • 145
  • 220
  • 6
    +1 It's also worth noting that in the OPs example the die function will be immediately garbage collected when freak() returns since no outside reference was created, so only one instance will ever exist at a time ( in this and similar cases ). – Mike Edwards Nov 05 '13 at 00:29
  • 2
    "immediately garbage collected" - I don't think so; at least not in every browser. I do work with V8.NET, and the V8 engine only runs the native GC to collect objects when the host goes idle. In fact, C#.NET also doesn't bother to collect until memory gets low (or you force it). I believe V8, for performance reasons, only collects also when the memory gets lower (based on some threshold). – James Wilkins Feb 28 '14 at 00:15
  • What about functions defined in an arrow notation (ie, const f = () => { ... } ) - is the overhead 'very small and normally inconsequential' in that case also ? – kofifus Sep 22 '17 at 02:04
  • 2
    @kofifus The same general optimizations can be applied; furthermore, arrow functions may avoid an additional `this` binding (it turns into a potential capture vs. an invocation artifact). Outside of the most critical code / degenerate cases, functions are fair fair fair game. (Devices are also continuously become faster.) – user2864740 Sep 23 '17 at 05:44