Functions and function scope

  • Revision slug: Talk:JavaScript/Reference/Functions_and_function_scope
  • Revision title: Functions and function scope
  • Revision id: 15460
  • Created:
  • Creator: Ps
  • Is current revision? No
  • Comment

Revision Content

TODO: add section on this and method binding --Maian 02:45, 19 September 2005 (PDT)

Reorg

Since this page is getting large very fast, I'm planning on creating a category devoted to Core JavaScript 1.5 Reference:Functions that will have the following subcategories:

Because of name conflicts and for consistency, moving objects page to Core_JavaScript_1.5_Reference:Global Objects, top-level functions to Core_JavaScript_1.5_Reference:Global Functions, and top-level properties to Core_JavaScript_1.5_Reference:Global Properties.

Any comments? Name suggestions?

--Maian 07:04, 8 September 2005 (PDT)

Yes, this sounds fine. Thanks for your help! --Nickolay 12:11, 8 September 2005 (PDT)

About "Function constructor vs. function declaration vs. function expression" section

I'm going to just criticize it a bit, don't have time to write something better right now --Nickolay 04:00, 6 September 2005 (PDT)

1) The 4th example would better be

var multiply = function f(x, y) { return x * y; }

- to demonstrate the real difference between the function expression and function declaration, which is that function declaration affects the current scope, while function expression does not: alerting f after the above statement would cause a reference error.

Renamed the function name to func_name but feel free to change it to something more sensible. I already mentioned that func names can only be used in the function's body, but I'll clarify that section a bit. --Maian 06:57, 6 September 2005 (PDT)

We should also mention recursion here.

Agreed, though I wonder how many examples we'll need for that. --Maian 06:57, 6 September 2005 (PDT)

2) "static" isn't really a good term, I think, although I admit I don't have a better idea.

Well, I just changed it to "function's name can't be changed". --Maian 06:57, 6 September 2005 (PDT)

3) This doesn't work for me when executed in global scope, rv:1.8b4 Gecko/20050828. Haven't read the spec on it yet:

foo(); function foo() {alert('FOO!');}
That's odd. It works on Fx/1.06, IE/6SP2, Opera/8.02. In any case, it's part of the ECMAScript spec. Lemme dig it up... It says func declarations are parsed first before running the rest of the script. --Maian 06:57, 6 September 2005 (PDT)
Whoops, that was just the JS Shell I was using. It actually works fine. --Nickolay 08:28, 6 September 2005 (PDT)

4) I don't like using the "precompiled" term, when you actually mean "parsed only once".

I used "compiled" here for consistency, since the "general" subsection right under "description" also uses that term (and who knows where else): "declared functions are compiled". --Maian 06:57, 6 September 2005 (PDT)

5) I think the second list should be unordered, I first thought each item of that list was going to explain the corresponding declaration from the first list.

Agreed. --Maian 06:57, 6 September 2005 (PDT)

6) Should this section, the section about closures, etc. be separated from the main article? That would make it easier to link to them from other articles, and it would also make this article smaller and easier to scan.

Yes, but I don't know where it should be put. TBH, I don't think any of these function specifics should even be under the Function object. It should be put in a totally new chapter. Same thing applies for the method binding section. --Maian 06:57, 6 September 2005 (PDT)
I think we can just put it outside of the JS reference hierarchy. E.g. "Nested functions and closures in JavaScript" --Nickolay 08:28, 6 September 2005 (PDT)
Well, can you tell me what the scope of the reference is? I'm under the impression that anything important about JavaScript that concerns developers should be put there. --Maian 00:29, 7 September 2005 (PDT)
I didn't write it, so I don't know. I think this info is welcome as part of the reference. What I meant was - we are free to name the pages whatever we want. My original intention was to call it "Nested functions and closures in JavaScript", but maybe Core JavaScript Reference:Nested functions and closures would be more consistent with the rest of docs. Dria likes consistency. --Nickolay 02:34, 7 September 2005 (PDT)
But where would it appear on the reference TOC? Well in any case, I'll leave the reorganization to you. --Maian 02:37, 7 September 2005 (PDT)
Now that I think about it, there needs to be section devoted to functions in general. There are three places discussing functions: this section, function statement, and function operator. --Maian 03:45, 7 September 2005 (PDT)

About "Specifying an event handler with a Function object"

This section should be moved down to the example section and revised. The JS reference should be as DOM-independent as possible (with the exception of alert and window). Also, I think the "onEvent" naming has lost favor and should simply be called the "event" event, e.g. "onFocus" => "focus", to comply with the naming conventions set by DOM2 Events. --Maian 07:11, 6 September 2005 (PDT)

Name conflicts

Where I noticed name conflicts myself was when I was calling another function within a for (i=0;etc..) loop, and the function in question was using a for (i=0;etc..) loop, and the 2 i's were in conflict with each other. Simple fix was to rename the 2nd i to j instead. Perhaps this is a good example of the hidden pitfalls with using identically named functions?

new Function() vs function(){}

The article states that the code given to new Function() is parsed every time the function is executed and that function constructors should be avoided because of that. I did a few benchmarks (on Firefox 2.0.0.3, Spider Monkey 4.0 I think and Windows XP) and could not reproduce that.

Consider the following:

function test1() {
  var f = function(){ return 1; };
  for (var i = 0; i < 10000; i++) f();
}
function test2() {
  var f = new Function("return 1;");
  for (var i = 0; i < 10000; i++) f();
}
function test3() {
  for (var i = 0; i < 10000; i++) eval("1");
}
function test4() {
  for (var i = 0; i < 10000; i++) (new Function("return 1;"))();
}

test1() is running very fast as expected. test3() and test4() are crawling along, no surprise here either. But test2() which, according to the article, should have a similar speed as test4() or at least test3 runs on my machine actually as fast as test1(). For me this looks as if code passed in a function constructor is actually parsed once, when the function object is created and not each time it is executed. Which would make sense to me.

Don't get me wrong, I don't want to promote the use of new Function instead of function(){} here. I just want to point out, that, if you absolutely have to parse a string as code, new Function() is still a lot more efficient as eval().

Maybe the information in the article is from an old version of Spider Monkey? --Ps 08:05, 12 May 2007 (PDT)

Revision Source

<p>TODO: add section on <code>this</code> and method binding --<a href="User:Maian">Maian</a> 02:45, 19 September 2005 (PDT)
</p>
<h3 name="Reorg"> Reorg </h3>
<p>Since this page is getting large very fast, I'm planning on creating a category devoted to <a href="en/Core_JavaScript_1.5_Reference/Functions">Core JavaScript 1.5 Reference:Functions</a> that will have the following subcategories:
</p>
<ul><li> general info
</li><li> <a href="en/Core_JavaScript_1.5_Reference/Functions/arguments">Core JavaScript 1.5 Reference:Functions:arguments</a>
</li><li> calling functions (also create a call operator page and link to it)
<ul><li> <a href="en/Core_JavaScript_1.5_Reference/Functions/this">Core JavaScript 1.5 Reference:Functions:this</a>: <code>this</code> and method binding
</li></ul>
</li><li> ways to create functions (links to <a href="en/Core_JavaScript_1.5_Reference/Objects/Function">Core_JavaScript_1.5_Reference:Objects:Function</a>, <a href="en/Core_JavaScript_1.5_Reference/Statements/function">Core_JavaScript_1.5_Reference:Statements:function</a>, and <a href="en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/function_Operator">Core_JavaScript_1.5_Reference:Operators:Special_Operators:function_Operator</a>)
<ul><li> <a href="en/Core_JavaScript_1.5_Reference/Functions/Function_constructor_vs._function_declaration_vs._function_expression">Core JavaScript 1.5 Reference:Functions:Function constructor vs. function declaration vs. function expression</a>
</li></ul>
</li><li> <a href="en/Core_JavaScript_1.5_Reference/Functions/Nested_functions_and_closures">Core JavaScript 1.5 Reference:Functions:Nested functions and closures</a>
</li></ul>
<p>Because of name conflicts and for consistency, moving objects page to <a href="en/Core_JavaScript_1.5_Reference/Global_Objects">Core_JavaScript_1.5_Reference:Global Objects</a>, top-level functions to <a href="en/Core_JavaScript_1.5_Reference/Global_Functions">Core_JavaScript_1.5_Reference:Global Functions</a>, and top-level properties to <a href="en/Core_JavaScript_1.5_Reference/Global_Properties">Core_JavaScript_1.5_Reference:Global Properties</a>.
</p><p>Any comments? Name suggestions?
</p><p>--<a href="User:Maian">Maian</a> 07:04, 8 September 2005 (PDT)
</p>
<dl><dd> Yes, this sounds fine. Thanks for your help! --<a href="User:Nickolay">Nickolay</a> 12:11, 8 September 2005 (PDT)
</dd></dl>
<h3 name="About_.22Function_constructor_vs._function_declaration_vs._function_expression.22_section"> About "Function constructor vs. function declaration vs. function expression" section </h3>
<p>I'm going to just criticize it a bit, don't have time to write something better right now --<a href="User:Nickolay">Nickolay</a> 04:00, 6 September 2005 (PDT)
</p><p>1) The 4th example would better be 
</p>
<pre class="eval">var multiply = function f(x, y) { return x * y; }
</pre>
<p>- to demonstrate the real difference between the function expression and function declaration, which is that function declaration affects the current scope, while function expression does not: alerting <code>f</code> after the above statement would cause a reference error.
</p>
<dl><dd> Renamed the function name to func_name but feel free to change it to something more sensible. I already mentioned that func names can only be used in the function's body, but I'll clarify that section a bit. --<a href="User:Maian">Maian</a> 06:57, 6 September 2005 (PDT)
</dd></dl>
<p>We should also mention recursion here.
</p>
<dl><dd> Agreed, though I wonder how many examples we'll need for that. --<a href="User:Maian">Maian</a> 06:57, 6 September 2005 (PDT)
</dd></dl>
<p>2) "static" isn't really a good term, I think, although I admit I don't have a better idea.
</p>
<dl><dd> Well, I just changed it to "function's name can't be changed". --<a href="User:Maian">Maian</a> 06:57, 6 September 2005 (PDT)
</dd></dl>
<p>3) This doesn't work for me when executed in global scope, rv:1.8b4 Gecko/20050828. Haven't read the spec on it yet:
</p>
<pre class="eval">foo(); function foo() {alert('FOO!');}
</pre>
<dl><dd> That's odd. It works on Fx/1.06, IE/6SP2, Opera/8.02. In any case, it's part of the ECMAScript spec. Lemme dig it up... <a class="external" href="http://bclary.com/2004/11/07/ecma-262#a-14"> It says func declarations are parsed first before running the rest of the script. --</a><a href="User:Maian">Maian</a> 06:57, 6 September 2005 (PDT)
</dd></dl>
<dl><dd><dl><dd> Whoops, that was just the JS Shell I was using. It actually works fine. --<a href="User:Nickolay">Nickolay</a> 08:28, 6 September 2005 (PDT)
</dd></dl>
</dd></dl>
<p>4) I don't like using the "precompiled" term, when you actually mean "parsed only once".
</p>
<dl><dd> I used "compiled" here for consistency, since the "general" subsection right under "description" also uses that term (and who knows where else): "declared functions are compiled". --<a href="User:Maian">Maian</a> 06:57, 6 September 2005 (PDT)
</dd></dl>
<p>5) I think the second list should be unordered, I first thought each item of that list was going to explain the corresponding declaration from the first list.
</p>
<dl><dd> Agreed. --<a href="User:Maian">Maian</a> 06:57, 6 September 2005 (PDT)
</dd></dl>
<p>6) Should this section, the section about closures, etc. be separated from the main article? That would make it easier to link to them from other articles, and it would also make this article smaller and easier to scan.
</p>
<dl><dd> Yes, but I don't know where it should be put. TBH, I don't think any of these function specifics should even be under the Function object. It should be put in a totally new chapter. Same thing applies for the <a href="en/Core_JavaScript_1.5_Reference/Operators/Member_Operators">method binding</a> section. --<a href="User:Maian">Maian</a> 06:57, 6 September 2005 (PDT)
</dd></dl>
<dl><dd><dl><dd> I think we can just put it outside of the JS reference hierarchy. E.g. "Nested functions and closures in JavaScript" --<a href="User:Nickolay">Nickolay</a> 08:28, 6 September 2005 (PDT)
</dd></dl>
</dd></dl>
<dl><dd><dl><dd><dl><dd> Well, can you tell me what the scope of the reference is? I'm under the impression that anything important about JavaScript that concerns developers should be put there. --<a href="User:Maian">Maian</a> 00:29, 7 September 2005 (PDT)
</dd></dl>
</dd></dl>
</dd></dl>
<dl><dd><dl><dd><dl><dd><dl><dd> I didn't write it, so I don't know. I think this info is welcome as part of the reference. What I meant was - we are free to name the pages whatever we want. My original intention was to call it "Nested functions and closures in JavaScript", but maybe <a href="en/Core_JavaScript_Reference/Nested_functions_and_closures">Core JavaScript Reference:Nested functions and closures</a> would be more consistent with the rest of docs. Dria likes consistency. --<a href="User:Nickolay">Nickolay</a> 02:34, 7 September 2005 (PDT)
</dd></dl>
</dd></dl>
</dd></dl>
</dd></dl>
<dl><dd><dl><dd><dl><dd><dl><dd><dl><dd> But where would it appear on the reference TOC? Well in any case, I'll leave the reorganization to you. --<a href="User:Maian">Maian</a> 02:37, 7 September 2005 (PDT)
</dd></dl>
</dd></dl>
</dd></dl>
</dd></dl>
</dd></dl>
<dl><dd><dl><dd><dl><dd><dl><dd><dl><dd><dl><dd> Now that I think about it, there needs to be section devoted to functions in general. There are three places discussing functions: this section, function statement, and function operator. --<a href="User:Maian">Maian</a> 03:45, 7 September 2005 (PDT)
</dd></dl>
</dd></dl>
</dd></dl>
</dd></dl>
</dd></dl>
</dd></dl>
<h3 name="About_.22Specifying_an_event_handler_with_a_Function_object.22"> About "Specifying an event handler with a Function object" </h3>
<p>This section should be moved down to the example section and revised. The JS reference should be as DOM-independent as possible (with the exception of <code>alert</code> and <code>window</code>). Also, I think the "onEvent" naming has lost favor and should simply be called the "event" event, e.g. "onFocus" =&gt; "focus", to comply with the naming conventions set by DOM2 Events. --<a href="User:Maian">Maian</a> 07:11, 6 September 2005 (PDT)
</p>
<h3 name="Name_conflicts"> Name conflicts </h3>
<p>Where I noticed name conflicts myself was when I was calling another function within a for (i=0;etc..) loop, and the function in question was using a for (i=0;etc..) loop, and the 2 i's were in conflict with each other.  Simple fix was to rename the 2nd i to j instead.  Perhaps this is a good example of the hidden pitfalls with using identically named functions?
</p>
<h3 name="new_Function.28.29_vs_function.28.29{}"> <code>new Function()</code> vs <code>function(){}</code> </h3>
<p>The article states that the code given to <code>new Function()</code> is parsed <i>every time the function is executed</i> and that function constructors should be avoided because of that. I did a few benchmarks (on Firefox 2.0.0.3, Spider Monkey 4.0 I think and Windows XP) and could not reproduce that. 
</p><p>Consider the following:
</p>
<pre class="eval">function test1() {
  var f = function(){ return 1; };
  for (var i = 0; i &lt; 10000; i++) f();
}
</pre>
<pre class="eval">function test2() {
  var f = new Function("return 1;");
  for (var i = 0; i &lt; 10000; i++) f();
}
</pre>
<pre class="eval">function test3() {
  for (var i = 0; i &lt; 10000; i++) eval("1");
}
</pre>
<pre class="eval">function test4() {
  for (var i = 0; i &lt; 10000; i++) (new Function("return 1;"))();
}
</pre>
<p><code>test1()</code> is running very fast as expected. <code>test3()</code> and <code>test4()</code> are crawling along, no surprise here either.
But <code>test2()</code> which, according to the article, should have a similar speed as <code>test4()</code> or at least <code>test3</code> runs on my machine actually as fast as <code>test1()</code>.
For me this looks as if code passed in a function constructor is actually parsed <i>once</i>, when the function object is created and not each time it is executed. Which would make sense to me.
</p><p>Don't get me wrong, I don't want to promote the use of <code>new Function</code> instead of <code>function(){}</code> here. I just want to point out, that, if you absolutely have to parse a string as code, <code>new Function()</code> is still a lot more efficient as <code>eval()</code>.
</p><p>Maybe the information in the article is from an old version of Spider Monkey?
--<a href="User:Ps">Ps</a> 08:05, 12 May 2007 (PDT)
</p>
Revert to this revision