2

Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}

In Javascript, "private methods" are basically just inner functions. But throughout the various javascript tutorials available online, there seems to be two practices for declaring private methods:

function foo()
{
  var privateMethod = function() { }
}

versus...

function foo()
{
  function privateMethod() { }
}

They both seem to achieve the same effect, i.e. privateMethod is not accessible publicly through an instance of foo. The only difference seems to be with the first way (using the var keyword), privateMethod is only available to code that comes after the declaration. But with the second way, privateMethod is available to all code within foo. So, is there any other difference that makes either of these two practices preferable?

Community
  • 1
  • 1
Channel72
  • 22,459
  • 30
  • 97
  • 168

1 Answers1

1

There's another major difference: In the first example, the function is anonymous. The variable it's assigned to has a name, but the function itself does not. This matters when you're using the debugger and looking at lists of breakpoints, the call stack, etc.

Another major difference is that the first, which is called a function expression, happens as of when the execution point reaches that part of the code, which means you can assign different functions to the variable depending on the logic flow if you want. The second, which is called a function declaration, is only valid at the top level of its containing scope (not within an if block, a try/catch, etc.), and happens when execute enters that containing scope (before any step-by-step code is run).

You might well be tempted to combine the two, using a named function expression:

var foo = function foo() { ... };

...but sadly although it should be valid, various JavaScript engines (primarily Microsoft's) handle those incorrectly.

T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • http://jsfiddle.net/cJHCL/ contradicts the second part of your statement for me in Chrome – Alexander Pavlov Feb 22 '12 at 14:23
  • @AlexanderPavlov: Chrome is just tolerating invalid syntax; see Sections [12](http://es5.github.com/#x12) (specifically the big "NOTE"), [13](http://es5.github.com/#x13), and [10.5](http://es5.github.com/#x10.5) of the specification. Try it on Firefox, which follows the letter of the law. But on Chrome, here are some more interesting cases, and examples of why you Don't Do This: http://jsfiddle.net/cJHCL/1/ http://jsfiddle.net/cJHCL/2/ – T.J. Crowder Feb 22 '12 at 14:28
  • Absolutely, this is a big Don't Do This, just pointing out that it works on Chrome (v8, actually.) OTOH, JS allows things like `if (foo) { var value = val1; } else { var value = val2; /* or omit this altogether to get "undefined" in value */ }` which is also somewhat confusing. – Alexander Pavlov Feb 22 '12 at 14:31
  • @AlexanderPavlov: It can be confusing if you're not familiar with [poor misunderstood `var`](http://blog.niftysnippets.org/2008/03/poor-misunderstood-var.html), but it *is* clearly defined in the specification (also in Section 10.5). In ECMAScript6 we'll be getting `let`, which unlike `var` has block scope. Just to confuse people further. :-) (I'm not putting it down, `let` will be useful. But it *will* confuse people.) – T.J. Crowder Feb 22 '12 at 14:35
  • Great article, indeed! :) I'm actually speaking about the code readability - so easy to lose the declaration in a big block... – Alexander Pavlov Feb 22 '12 at 14:45
  • @AlexanderPavlov: Thanks. Yeah, that's why I always put all `var` declarations at the top, where they take effect. As I said in the article, we don't actively dislike the person who has to come along later and edit our code, right? So let's throw 'em a bone. :-) – T.J. Crowder Feb 22 '12 at 15:14