Prev: FAQ Topic - How do I format a Number as a String with exactly2 decimal places? (2010-03-30)
Next: Closing parenthesis in function's definition followed by itscall
From: VK on 20 Apr 2010 14:01 On Apr 20, 5:55 am, Johannes Baagoe <baa...(a)baagoe.com> wrote: > Should it be > > (function foo() { /*...*/ })(); > > or > > (function foo() { /*...*/ }()); > > (note the place of the closing parenthesis) ? From the pretty-print point of view I might like the second better as a fully enclosed construct, without emty parenthesis pending on the right side. From the other side provokes to try function foo() { / *...*/ }() which is not correct without an expression context. By its nature the question is dangerously close to "same line vs. next line bracket placement" and similar rwar topics :-) so I would just suggest to use either w/o attacking each other :-) Please note the different named function handling in IE and other UAs: in IE (function foo() { /*...*/ })() is equivalent (with some subtle details) to: function foo() { /*...*/ }; foo(); so foo is created and remains in the namespace - the standard test I'm periodically running to monitor possible changes is at the end of the post. For the fairness sake IE's behavior equals to Netscape 3.x -4.x: so the guys went out of business first and then decided that it should work in some other way. This is why for FunctionExpression only anonymous functions are normally used. > Same question for > > var foo = (function() { /*...*/ })(); > > vs. > > var foo = (function() { /*...*/ }()); > > etc. Same answer as above I guess with the same named functions warning. Also here parenthesis are not necessary, unlike in the first case: expression context implied by the function position in right side of the assignment. Also note that: function foo() { /*...*/ } and var foo = function foo() { /*...*/ }; are not equal by their internal organization. In the first case we get one dispid in the name table for "foo" (spitting 3 times over the shoulder let's say *foo - dispid is not a *pointer but functionally is a relative of it). In the second case you get 2 dispids: one for the anonymous function, the other one for "foo". So in the first case: look for foo -> get pointer to the function -> get the function in the second case: look for foo -> get pointer to anonymous -> look for anonymous -> get pointer to the function -> get the function It is true at least for IE - thus sufficient do not endorse function assignments as the only way of coding. Yet it is in a big fashion right now, especially among programmers certified in other languages. In my office I lock such attempts right away, here I would assign it to yet another rwar topic :-) FunctionExpression discrepancies test: <!DOCTYPE html> <html> <head> <title>Demo</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <script type="text/javascript"> (function foo(){/*NOP*/}()) function demo() { window.alert(typeof foo); } window.onload = function() { window.setTimeout('demo()',10) } </script> </head> <body> <h1>Demo</h1> </body> </html>
From: nick on 20 Apr 2010 01:05 On Apr 19, 9:55 pm, Johannes Baagoe <baa...(a)baagoe.com> wrote: > Same question for > > var foo = (function() { /*...*/ })(); > > vs. > > var foo = (function() { /*...*/ }()); Those shouldn't need the extra parentheses... var foo = function() { /*...*/ }(); ....should be valid. But nobody ever does that, which makes me think some old(ish) browsers might be more picky, especially after reading this: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Functions #Function_constructor_vs._function_declaration_vs._function_expression "Some JavaScript engines, not including SpiderMonkey, incorrectly treat any function expression with a name as a function definition" -- Nick
From: Thomas 'PointedEars' Lahn on 20 Apr 2010 08:53 Johannes Baagoe wrote: > Should it be > > (function foo() { /*...*/ })(); > > or > > (function foo() { /*...*/ }()); > > (note the place of the closing parenthesis) ? > > Both are AFAICT syntactically correct and indeed equivalent, but > I would tend to prefer the latter: since we are warning the future > reader "Beware! This function is not only defined / declared but also > called right away!", why not make it quite clear where the scope of > that warning ends? Incidentally, that is what Douglas Crockford recommends and the way his argument goes, too, as you can see starting at about 00:29:27 h of "Act III: Function the Ultimate" (when he starts talking about closures).¹ Contrary to other of his opinions, I find the reasoning sound in this case, and have rewritten function expression calls on occasion. I have tested the result with various browsers and have observed no negative effects so far. ¹ <http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-3> > Same question for > > var foo = (function() { /*...*/ })(); > > vs. > > var foo = (function() { /*...*/ }()); Currently I am using such assignments more often than one of the statements above, although to real properties (which become methods), seldom to variables. > etc. > > It doesn't matter much when `foo` is called with an empty list > of arguments, but I believe it would make cases where its arguments > are complex much clearer - any editor that matches opening and closing > parentheses would immediately show the various parts of the construct. Full ACK. > Are there better arguments in favour of the former ? I don't think so. PointedEars -- Anyone who slaps a 'this page is best viewed with Browser X' label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network. -- Tim Berners-Lee
From: Jorge on 20 Apr 2010 09:11 On Apr 20, 3:55 am, Johannes Baagoe <baa...(a)baagoe.com> wrote: > Should it be > > (function foo() { /*...*/ })(); > > or > > (function foo() { /*...*/ }()); > > (note the place of the closing parenthesis) ? > > Both are AFAICT syntactically correct and indeed equivalent, but > I would tend to prefer the latter: since we are warning the future > reader "Beware! This function is not only defined / declared but also > called right away!", why not make it quite clear where the scope of > that warning ends? > > Same question for > > var foo = (function() { /*...*/ })(); > > vs. > > var foo = (function() { /*...*/ }()); > > etc. > > It doesn't matter much when `foo` is called with an empty list > of arguments, but I believe it would make cases where its arguments > are complex much clearer - any editor that matches opening and closing > parentheses would immediately show the various parts of the construct. > > Are there better arguments in favour of the former ? I prefer the former, for as soon as I see a () my "attention: function call" flag gets set, and I expect the function itself to stand by the left hand side of the (), often neatly enclosed in its own parens. A trailing ()) is not so neat and tidy. It's asymmetric and awful. This is one of the rare cases in which Crockford's arguments have not convinced me. -- Jorge.
From: Jorge on 20 Apr 2010 13:21
On Apr 20, 7:05 am, nick <nick...(a)fastmail.fm> wrote: > > "Some JavaScript engines, not including SpiderMonkey, incorrectly > treat any function expression with a name as a function definition" LOL. And these engines are made by Microsoft and are called JScript and are the ones used in each and every Internet Explorer, up to and including the current, latest one. And they manage miraculously to not only screw up the function expression, but the function declaration too. Wonders of software engineering. -- Jorge. |