2

Alright, I know what's the difference between a FunctionDeclaration and a FunctionExpression. @CMS did a great job of explaining that. Till recently, I used to use the same syntax for creating lambda expressions and namespaces following Douglas Crockford's example:

(function () {
    "use strict";
}());

He justifies this convention as follows:

When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.

This syntax is great for lambda expressions because they return a value. However, namespaces do not return a value. Hence I now prefer using the following syntax for namespaces instead (taken from the JavaScript Garden):

(function () {
    "use strict";
})();

The rationale behind the use of this syntax is given as follows:

( // evaluate the function inside the paranthesis
function() {}
) // and return the function object
() // call the result of the evaluation

Using this syntax for namespaces makes more sense to me because: this syntax separates the namespace and the invocation; and Douglas Crockford's syntax expects the function to return a value.

However, when I pass this syntax through JSLint I get the an error stating "Move the invocation into the parens that contain the function.". I don't understand why it complains about this syntax. It's a widely used and accepted syntax.

I plan on notifying Douglas Crockford about this problem. However, before I do so I would appreciate any feedback you may provide. Perhaps it's better to simply stick with his syntax? Please explain your views.

Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • 4
    It complains about the syntax because it's Mr. Crockford's opinion that it should. That's really all JSLint is: a robotic encapsulation of Crock's opinions about JavaScript coding style. – Pointy Oct 31 '11 at 14:40
  • Indeed, but it's really annoying when JSLint imposes its preferred coding style on everybody. I use JSLint regularly and it pains me to see my perfectly semantic good code generating errors. – Aadit M Shah Oct 31 '11 at 14:48
  • 2
    There's [jsHint](http://www.jshint.com) for people that don't want to follow Crockfords standards, he's not going to change them because he has spent a lot of time determining best practices for team development of javascript. – JaredMcAteer Oct 31 '11 at 14:56
  • @OriginalSyn - Wow, I'm really glad someone made that. Thanks for sharing the link. =) – Aadit M Shah Oct 31 '11 at 15:01
  • As a side note, I don't see anything wrong in Crockford approach to this use case and it seems to me pretty consisten. Namespace declaration is and remains a function call and a function call always returns a value. this value is undefined if there is no return statement in the function; it's, though, nonetheless a returned value. – Davide Mar 09 '12 at 19:45
  • @Davide - While it's true that functions in Javascript always return a value enforcing one's coding conventions on others is not acceptable. To state clearly when I say _"namespaces don't return a value"_ I mean that the value returned by a namespace is not stored in a variable - hence _there's no need to clarify that the value being produced is the result of the function and not the function itself_. This makes Crockford's justification null and void. Separating the namespace and invocation makes sense because it documents the fact that the function being invoked is not a lamba expression. ;) – Aadit M Shah Mar 10 '12 at 07:19
  • it has been discussed in more detail here http://stackoverflow.com/questions/8774425/vs-in-javascript-closures – jJ' May 03 '12 at 15:02

1 Answers1

1

In retrospect I believe Crockford's views are simply dogma. He says:

When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.

Well my arguments is that when a function is being invoked immediately how is it not clear that the value being produced is the result of the function and not the function itself? Consider:

The value being produced is the function:

var f = function () {
    "use strict;"
};

The value being produced is the result of the function:

var x = (function () {
    "use strict;"
})();

If you want the value being produced to be the function itself then simply don't use parens. It doesn't make sense to use them anyway.

Understandably there are many programmers who would still wrap a function expression in parentheses before assigning it to a variable, or who would be a sadist and do something like this to confuse Doug:

var x = function () {
    "use strict;"
}();

However how difficult is it to understand what's going on? Perhaps in the last example you would need to scroll down several hundreds of lines of code to find out but a good programmer would save others the trouble and just wrap the function in parens; or if he's a miser:

var x = ~function () {
    "use strict;"
}();

Beside I wouldn't even bother reading code written by someone who's hell bent on making me curse him. Coming back to the question though the reason I really dislike Crockford's syntax is because he's grouping the function and invocation in a single parentheses. To me that's equivalent to the following:

var x = (f());

function f() {
    "use strict;"
}

Obviously wrapping a function invocation in parens looks a little silly and redundant but that's how I imagine it to be and it always irks me, but every man to his own way. Personally I think my syntax looks cleaner.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299