Compare Revisions

Functions

Revision 267012:

Revision 267012 by drygunin on

Revision 207727:

Revision 207727 by drygunin on

Title:
Functions
Functions
Slug:
Ядро_JavaScript_1.5_Спровчник/Functions
Ядро_JavaScript_1.5_Спровчник/Functions
Content:

Revision 267012
Revision 207727
t7    <p>t
8      &nbsp;
9    </p>
10    <h3 id="Summary" name="Summary">
11      Summary
12    </h3>
13    <p>
14      Generally speaking, a function is a "subprogram" that can b
>e <em>called</em> by code external (or internal in the case of re 
>cursion) to the function. Like the program itself, a function is  
>composed of a sequence of statements called the <em>function body 
></em>. Objects and values can be <em>passed</em> to a function, a 
>nd the function can <em>return</em> an object or value. 
15    </p>
16    <p>
17      In JavaScript, functions are first-class objects, i.e. they
> are objects and can be manipulated and passed around like just l 
>ike any other object. Specifically, they are <code><a href="/ru/C 
>ore_JavaScript_1.5_Reference/Global_Objects/Function" title="ru/C 
>ore_JavaScript_1.5_Reference/Global_Objects/Function">Function</a 
>></code> objects. 
18    </p>
19    <h3 id="General" name="General">
20      General
21    </h3>
22    <p>
23      Каждая функция в JavaScript на самом деле является объектом
> типа <code>Function</code>. See <code><a href="/ru/Core_JavaScri 
>pt_1.5_Reference/Global_Objects/Function" title="ru/Core_JavaScri 
>pt_1.5_Reference/Global_Objects/Function">Function</a></code> for 
> information on properties and methods of <code>Function</code> o 
>bjects. 
24    </p>
25    <p>
26      Чтобы вернуть значение, функция должна иметь оператор <code
>><a href="/ru/Core_JavaScript_1.5_Reference/Statements/return" ti 
>tle="ru/Core_JavaScript_1.5_Reference/Statements/return">return</ 
>a></code>, который определяет возвращаемое значение. Функция, не  
>имеющая определённого возвращаемого значения, возвращает <code>un 
>defined</code>. 
27    </p>
28    <p>
29      Non-object parameters, e.g. strings, numbers and booleans, 
>are passed to functions <em>by value</em>; the value is passed to 
> the function where it is stored in a new variable. If the functi 
>on changes the value of the variable, this change is not reflecte 
>d globally or in the calling function. Object parameters, e.g. ob 
>jects, arrays and regular expressions, are passed to functions <e 
>m>by reference</em>; if you pass an object as a parameter to a fu 
>nction and the function changes the object's properties, that cha 
>nge is visible outside the function, as shown in the following ex 
>ample: 
30    </p>
31    <pre>
32 function myFunc(theObject) {
33    theObject.brand = "Toyota";
34 }
35 
36 var mycar = {brand: "Honda", model: "Accord", year: 1998};
37 alert(mycar.brand); // shows 'Honda'
38 myFunc(mycar);      // pass object mycar to the function
39 alert(mycar.brand); // shows 'Toyota' as the brand property of
40                     // mycar was changed by the function)
41</pre>
42    <p>
43      The <code>this</code> keyword does not refer to the current
>ly executing function, so you must refer to <code>Function</code> 
> objects by name, even within the function body. Alternatively, y 
>ou can use the <a href="/ru/Core_JavaScript_1.5_Reference/Functio 
>ns/arguments/callee" title="ru/Core_JavaScript_1.5_Reference/Func 
>tions/arguments/callee">arguments.callee</a> property. 
44    </p>
45    <h3 id="Defining_functions" name="Defining_functions">
46      Defining functions
47    </h3>
48    <p>
49      There are three ways to define functions:
50    </p>
51    <h4 id="The_function_declaration_.28function_statement.29" na
>me="The_function_declaration_.28function_statement.29"> 
52      The function declaration (<code>function</code> statement)
53    </h4>
54    <p>
55      There is a special syntax for declaring functions (see <a h
>ref="/ru/Core_JavaScript_1.5_Reference/Statements/function" title 
>="ru/Core_JavaScript_1.5_Reference/Statements/function">function  
>statement</a> for details): 
56    </p>
57    <pre class="eval">
58function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em
>>param</em>]]]) { 
59   <em>statements</em>
60}
61</pre>
62    <dl>
63      <dt>
64        <code>name</code>
65      </dt>
66      <dd>
67        The function name.
68      </dd>
69    </dl>
70    <dl>
71      <dt>
72        <code>param</code>
73      </dt>
74      <dd>
75        The name of an argument to be passed to the function. A f
>unction can have up to 255 arguments. 
76      </dd>
77    </dl>
78    <dl>
79      <dt>
80        <code>statements</code>
81      </dt>
82      <dd>
83        The statements comprising the body of the function.
84      </dd>
85    </dl>
86    <h4 id="The_function_expression_.28function_operator.29" name
>="The_function_expression_.28function_operator.29"> 
87      The function expression (<code>function</code> operator)
88    </h4>
89    <p>
90      A function expression is similar to and has the same syntax
> as a function declaration (see <a href="/ru/Core_JavaScript_1.5_ 
>Reference/Operators/Special_Operators/function_Operator" title="r 
>u/Core_JavaScript_1.5_Reference/Operators/Special_Operators/funct 
>ion_Operator">function operator</a> for details): 
91    </p>
92    <pre class="eval">
93function [<em>name</em>]([<em>param</em>] [, <em>param</em>] [...
>, <em>param</em>]) { 
94   <em>statements</em>
95}
96</pre>
97    <dl>
98      <dt>
99        <code>name</code>
100      </dt>
101      <dd>
102        Имя функции. Может отсутствовать, в этом случае функция б
>удет анонимной. 
103      </dd>
104    </dl>
105    <dl>
106      <dt>
107        <code>param</code>
108      </dt>
109      <dd>
110        Имя аргумента, передаваемого функции. Функция может прини
>мать до 255 аргументов. 
111      </dd>
112    </dl>
113    <dl>
114      <dt>
115        <code>statements</code>
116      </dt>
117      <dd>
118        Выражения, составляющие тело функции.
119      </dd>
120    </dl>
121    <h4 id="The_Function_constructor" name="The_Function_construc
>tor"> 
122      The <code>Function</code> constructor
123    </h4>
124    <p>
125      Как и любые другие объекты, объекты <code>Function</code> м
>огут быть созданы с использованием оператора <code>new</code> : 
126    </p>
127    <pre class="eval">
128new Function ([<em>arg1</em>[, <em>arg2</em>[, ... <em>argN</em>]
>],] <em>functionBody</em>) 
129</pre>
130    <dl>
131      <dt>
132        <code>arg1, arg2, ... arg<em>N</em></code>
133      </dt>
134      <dd>
135        Идентификаторы, которые будут использоваться&nbsp; функци
>ей как имена формальных аргументов. Каждый должен быть строкой, к 
>оторая является&nbsp; допустимым идентификатором JavaScript. Спис 
>ок аргументов разделяется запятыми. Например "<code>x</code>", "< 
>code>theValue</code>" или "<code>a,b,c</code>". 
136      </dd>
137    </dl>
138    <dl>
139      <dt>
140        <code>functionBody</code>
141      </dt>
142      <dd>
143        A string containing the JavaScript statements comprising 
>the function definition. 
144      </dd>
145    </dl>
146    <p>
147      Invoking the <code>Function</code> constructor as a functio
>n (without using the <code>new</code> operator) has the same effe 
>ct as invoking it as a constructor. 
148    </p>
149    <h3 id="The_arguments_object" name="The_arguments_object">
150      The <code>arguments</code> object
151    </h3>
152    <p>
153      You can refer to a function's arguments within the function
> by using the <code>arguments</code> object. See <a href="/ru/Cor 
>e_JavaScript_1.5_Reference/Functions/arguments" title="ru/Core_Ja 
>vaScript_1.5_Reference/Functions/arguments">arguments</a>. 
154    </p>
155    <h3 id="Scope_and_the_function_stack" name="Scope_and_the_fun
>ction_stack"> 
156      Scope and the function stack
157    </h3>
158    <p>
159      <span class="comment">some section about scope and function
>s calling other functions</span> 
160    </p>
161    <h3 id="Recursion" name="Recursion">
162      Recursion
163    </h3>
164    <p>
165      A function can refer to and call itself. There are three wa
>ys for a function to refer to itself: 
166    </p>
167    <ol>
168      <li>the function's name
169      </li>
170      <li>
171        <code><a href="/ru/Core_JavaScript_1.5_Reference/Function
>s/arguments/callee" title="ru/Core_JavaScript_1.5_Reference/Funct 
>ions/arguments/callee">arguments.callee</a></code> 
172      </li>
173      <li>an in-scope variable that refers to the function
174      </li>
175    </ol>
176    <p>
177      For example, consider the following function definition:
178    </p>
179    <pre class="eval">
180var foo = function bar() {
181   // statements go here
182};
183</pre>
184    <p>
185      Within the function body, the following are all equivalent:
186    </p>
187    <ol>
188      <li>
189        <code>bar()</code>
190      </li>
191      <li>
192        <code>arguments.callee()</code>
193      </li>
194      <li>
195        <code>foo()</code>
196      </li>
197    </ol>
198    <p>
199      A function that calls itself is called a <em>recursive func
>tion</em>. In some ways, recursion is analogous to a loop. Both e 
>xecute the same code multiple times, and both require a condition 
> (to avoid an infinite loop, or rather, infinite recursion in thi 
>s case). For example, the following loop: 
200    </p>
201    <pre class="eval">
202var x = 0;
203while (x &lt; 10) { // "x &lt; 10" is the loop condition
204   // do stuff
205   x++;
206}
207</pre>
208    <p>
209      can be converted into a recursive function and a call to th
>at function: 
210    </p>
211    <pre class="eval">
212function loop(x) {
213   if (x &gt;= 10) // "x &gt;= 10" is the exit condition (equival
>ent to "!(x &lt; 10)") 
214      return;
215   // do stuff
216   loop(x + 1); // the recursive call
217}
218loop(0);
219</pre>
220    <p>
221      However, some algorithms cannot be simple iterative loops. 
>For example, getting all the nodes of a tree structure (e.g. the  
><a href="/ru/DOM" title="ru/DOM">DOM</a>) is more easily done usi 
>ng recursion: 
222    </p>
223    <pre class="eval">
224function walkTree(node) {
225   if (node == null) // 
226      return;
227   // do something with node
228   for (var i = 0; i &lt; node.childNodes.length; i++) {
229      walkTree(node.childNodes[i]);
230   }
231}
232</pre>
233    <p>
234      Compared to the function <code>loop</code>, each recursive 
>call itself makes many recursive calls here. 
235    </p>
236    <p>
237      It is possible to convert any recursive algorithm to a non-
>recursive one, but often the logic is much more complex and doing 
> so requires the use of a stack. In fact, recursion itself uses a 
> stack: the function stack. 
238    </p>
239    <p>
240      The stack-like behavior can be seen in the following exampl
>e: 
241    </p>
242    <pre class="eval">
243function foo(i) {
244   if (i &lt; 0)
245      return;
246   document.writeln('begin:' + i);
247   foo(i - 1);
248   document.writeln('end:' + i);
249}
250foo(3);
251</pre>
252    <p>
253      which outputs:
254    </p>
255    <pre class="eval">
256begin:3
257begin:2
258begin:1
259begin:0
260end:0
261end:1
262end:2
263end:3
264</pre>
265    <h3 id="Nested_functions_and_closures" name="Nested_functions
>_and_closures"> 
266      Nested functions and closures
267    </h3>
268    <p>
269      You can nest a function within a function. The nested (inne
>r) function is private to its containing (outer) function. It als 
>o forms a <em>closure</em>. 
270    </p>
271    <dl>
272      <dd>
273        A closure is an expression (typically a function) that ca
>n have free variables together with an environment that binds tho 
>se variables (that "closes" the expression). <a class="external"  
>href="http://jibbering.com/faq/faq_notes/closures.html"></a> 
274      </dd>
275    </dl>
276    <p>
277      Since a nested function is a closure, this means that a nes
>ted function can "inherit" the arguments and variables of its con 
>taining function. In other words, the inner function contains the 
> scope of the outer function. 
278    </p>
279    <p>
280      To summarize:
281    </p>
282    <ul>
283      <li>The inner function can be accessed only from statements
> in the outer function. 
284      </li>
285    </ul>
286    <ul>
287      <li>The inner function forms a closure: the inner function 
>can use the arguments and variables of the outer function, while  
>the outer function cannot use the arguments and variables of the  
>inner function. 
288      </li>
289    </ul>
290    <p>
291      The following example shows nested functions:
292    </p>
293    <pre class="eval">
294function addSquares(a,b) {
295   function square(x) {
296      return x * x;
297   }
298   return square(a) + square(b);
299}
300a = addSquares(2,3); // returns 13
301b = addSquares(3,4); // returns 25
302c = addSquares(4,5); // returns 41
303</pre>
304    <p>
305      Since the inner function forms a closure, you can call the 
>outer function and specify arguments for both the outer and inner 
> function: 
306    </p>
307    <pre class="eval">
308function outside(x) {
309   function inside(y) {
310      return x + y;
311   }
312   return inside;
313}
314result = outside(3)(5); // returns 8
315</pre>
316    <h4 id="Efficiency_considerations" name="Efficiency_considera
>tions"> 
317      Efficiency considerations
318    </h4>
319    <p>
320      Notice how <code>x</code> is preserved when <code>inside</c
>ode> is returned. A closure preserves the arguments and variables 
> in all scopes it contains. Since each call provides potentially  
>different arguments, a closure must be created for each call to t 
>he outer function. In other words, each call to <code>outside</co 
>de> creates a closure. For this reason, closures can use up a lot 
> of memory. The memory can be freed only when the returned <code> 
>inside</code> is no longer accessible. In this case, the closure  
>of <code>inside</code> is stored in <code>result</code>. Since <c 
>ode>result</code> is in the global scope, the closure will remain 
> until the script is unloaded (in a browser, this would happen wh 
>en the page containing the script is closed). 
321    </p>
322    <p>
323      Because of this inefficiency, avoid closures whenever possi
>ble, i.e. avoid nesting functions whenever possible. For example, 
> consider the following example: 
324    </p>
325    <pre class="eval">
326function assignOnclick(element) {
327   element.onclick = function() {
328      this.style.backgroundColor = 'blue';
329   };
330}
331</pre>
332    <p>
333      This can be rewritten to avoid the closure. However, the an
>onymous inner function would need to be named and would no longer 
> be private to <code>assignOnclick</code>: 
334    </p>
335    <pre class="eval">
336function assignOnclick(element) {
337   element.onclick = element_onclick;
338}
339 
340function element_onclick() {
341   this.style.backgroundColor = 'blue';
342}
343</pre>
344    <h4 id="Multiply-nested_functions" name="Multiply-nested_func
>tions"> 
345      Multiply-nested functions
346    </h4>
347    <p>
348      Functions can be multiply-nested, i.e. a function (A) conta
>ining a function (B) containing a function (C). Both functions B  
>and C form closures here, so B can access A and C can access B. I 
>n addition, since C can access B which can access A, C can also a 
>ccess A. Thus, the closures can contain multiple scopes; they rec 
>ursively contain the scope of the functions containing it. This i 
>s called <em>scope chaining</em>. (Why it is called "chaining" wi 
>ll be explained later.) 
349    </p>
350    <p>
351      Consider the following example:
352    </p>
353    <pre class="eval">
354function A(x) {
355   function B(y) {
356      function C(z) {
357         alert(x + y + z);
358      }
359      C(3);
360   }
361   B(2);
362}
363A(1); // alerts 6 (1 + 2 + 3)
364</pre>
365    <p>
366      In this example, <code>C</code> accesses <code>B</code>'s <
>code>y</code> and <code>A</code>'s <code>x</code>. This can be do 
>ne because: 
367    </p>
368    <ol>
369      <li>
370        <code>B</code> forms a closure including <code>A</code>, 
>i.e. <code>B</code> can access <code>A</code>'s arguments and var 
>iables. 
371      </li>
372      <li>
373        <code>C</code> forms a closure including <code>B</code>.
374      </li>
375      <li>Because <code>B</code>'s closure includes <code>A</code
>>, <code>C</code>'s closure includes <code>A</code>, <code>C</cod 
>e> can access both <code>B</code> <em>and</em> <code>A</code>'s a 
>rguments and variables. In other words, <code>C</code> <em>chains 
></em> the scopes of <code>B</code> and <code>A</code> in that ord 
>er. 
376      </li>
377    </ol>
378    <p>
379      The reverse, however, is not true. <code>A</code> cannot ac
>cess <code>C</code>, because <code>A</code> cannot access any arg 
>ument or variable of <code>B</code>, which <code>C</code> is a va 
>riable of. Thus, <code>C</code> remains private to only <code>B</ 
>code>. 
380    </p>
381    <h4 id="Name_conflicts" name="Name_conflicts">
382      Name conflicts
383    </h4>
384    <p>
385      When two arguments or variables in the scopes of a closure 
>have the same name, there is a <em>name conflict</em>. More inner 
> scopes take precedence, so the inner-most scope takes the highes 
>t precedence, while the outer-most scope takes the lowest. This i 
>s the scope chain. The first on the chain is the inner-most scope 
>, and the last is the outer-most scope. Consider the following: 
386    </p>
387    <pre class="eval">
388function outside() {
389   var x = 10;
390   function inside(x) {
391      return x;
392   }
393   return inside;
394}
395result = outside()(20); // returns 20 instead of 10
396</pre>
397    <p>
398      The name conflict happens at the statement <code>return x</
>code> and is between <code>inside</code>'s parameter <code>x</cod 
>e> and <code>outside</code>'s variable <code>x</code>. The scope  
>chain here is {<code>inside</code>, <code>outside</code>, global  
>object}. Therefore <code>inside</code>'s <code>x</code> takes pre 
>cedences over <code>outside</code>'s <code>x</code>, and 20 (<cod 
>e>inside</code>'s <code>x</code>) is returned instead of 10 (<cod 
>e>outside</code>'s <code>x</code>). 
399    </p>
400    <h3 id="Function_constructor_vs._function_declaration_vs._fun
>ction_expression" name="Function_constructor_vs._function_declara 
>tion_vs._function_expression"> 
401      <code>Function</code> constructor vs. function declaration 
>vs. function expression 
402    </h3>
403    <p>
404      Compare the following:
405    </p>
406    <ol>
407      <li>a function defined with the <code>Function</code> const
>ructor assigned to the variable <code>multiply</code> 
408        <pre>
409var multiply = new Function("x", "y", "return x * y;");
410</pre>
411      </li>
412      <li>a <em>function declaration</em> of a function named <co
>de>multiply</code> 
413        <pre>
414function multiply(x, y) {
415   return x * y;
416}
417</pre>
418      </li>
419      <li>a <em>function expression</em> of an anonymous function
> assigned to the variable <code>multiply</code> 
420        <pre>
421var multiply = function(x, y) {
422   return x * y;
423}
424</pre>
425      </li>
426      <li>a function expression of a function named <code>func_na
>me</code> assigned to the variable <code>multiply</code> 
427        <pre>
428var multiply = function func_name(x, y) {
429   return x * y;
430}
431</pre>
432      </li>
433    </ol>
434    <p>
435      All do approximately the same thing, with a few subtle diff
>erences: 
436    </p>
437    <ul>
438      <li>There is a distinction between the function name and th
>e variable the function is assigned to: 
439        <ul>
440          <li>The function name cannot be changed, while the vari
>able the function is assigned to can be reassigned. 
441          </li>
442          <li>The function name can be used only within the funct
>ion's body. Attempting to use it outside the function's body resu 
>lts in an error (or <code>undefined</code> if the function name w 
>as previously declared via a <code>var</code> statement). For exa 
>mple: 
443            <pre>
444var y = function x() {};
445alert(x); // throws an error
446</pre>
447            <p>
448              The function name also appears when the function is
> serialized via <a href="/ru/Core_JavaScript_1.5_Reference/Global 
>_Objects/Function/toString" title="ru/Core_JavaScript_1.5_Referen 
>ce/Global_Objects/Function/toString"><code>Function</code>'s toSt 
>ring method</a>. 
449            </p>
450            <p>
451              On the other hand, the variable the function is ass
>igned to is limited only by its scope, which is guaranteed to inc 
>lude the scope where the function is declared in. 
452            </p>
453          </li>
454          <li>As the 4th example shows, the function name can be 
>different from the variable the function is assigned to. They hav 
>e no relation to each other. 
455          </li>
456        </ul>
457      </li>
458      <li>A function declaration also creates a variable with the
> same name as the function name. Thus, unlike those defined by fu 
>nction expressions, functions defined by function declarations ca 
>n be accessed by their name in the scope they were defined in: 
459        <pre>
460function x() {}
461alert(x); // outputs x serialized into a string
462</pre>
463        <p>
464          The following example shows how function names are not 
>related to variables functions are assigned to. If a "function va 
>riable" is assigned to another value, it will still have the same 
> function name: 
465        </p>
466        <pre>
467function foo() {}
468alert(foo); // alerted string contains function name "foo"
469var bar = foo;
470alert(bar); // alerted string still contains function name "foo"
471</pre>
472      </li>
473      <li>A function defined by a <code>Function</code> does not 
>have a function name. However, in the <a href="/ru/SpiderMonkey"  
>title="ru/SpiderMonkey">SpiderMonkey</a> JavaScript engine, the s 
>erialized form of the function shows as if it has the name "anony 
>mous". For example, <code>alert(new Function())</code> outputs: 
474        <pre>
475function anonymous() {
476}
477</pre>
478        <p>
479          Since the function actually does not have a name, <code
>>anonymous</code> is not a variable that can be accessed within t 
>he function. For example, the following would result in an error: 
480        </p>
481        <pre>
482var foo = new Function("alert(anonymous);");
483foo();
484</pre>
485      </li>
486      <li>Unlike functions defined by function expressions or by 
>the <code>Function</code> constructor, a function defined by a fu 
>nction declaration can be used before the function declaration it 
>self. For example: 
487        <pre>
488foo(); // alerts FOO!
489function foo() {
490   alert('FOO!');
491}
492</pre>
493      </li>
494      <li>A function defined by a function expression inherits th
>e current scope. That is, the function forms a closure. On the ot 
>her hand, a function defined by a <code>Function</code> construct 
>or does not inherit any scope other than the global scope (which  
>all functions inherit). 
495      </li>
496      <li>Functions defined by function expressions and function 
>declarations are parsed only once, while those defined by the <co 
>de>Function</code> constructor are not. That is, the function bod 
>y string passed to the <code>Function</code> constructor must be  
>parsed every time it is evaluated. Although a function expression 
> creates a closure every time, the function body is not reparsed, 
> so function expressions are still faster than "<code>new Functio 
>n(...)</code>". Therefore the <code>Function</code> constructor s 
>hould be avoided whenever possible. 
497      </li>
498    </ul>
499    <p>
500      A function declaration is very easily (and often unintentio
>nally) turned into a function expression. A function declaration  
>ceases to be one when it either: 
501    </p>
502    <ul>
503      <li>becomes part of an expression
504      </li>
505      <li>is no longer a "source element" of a function or the sc
>ript itself. A "source element" is a non-nested statement in the  
>script or a function body: 
506        <pre>
507var x = 0;               // source element
508if (x == 0) {            // source element
509   x = 10;               // not a source element
510   function boo() {}     // not a source element
511}
512function foo() {         // source element
513   var y = 20;           // source element
514   function bar() {}     // source element
515   while (y == 10) {     // source element
516      function blah() {} // not a source element
517      y++;               // not a source element
518   }
519}
520</pre>
521      </li>
522    </ul>
523    <p>
524      Examples:
525    </p>
526    <ul>
527      <li>
528        <pre>
529// function declaration
530function foo() {}
531 
532// function expression
533(function bar() {})
534 
535// function expression
536x = function hello() {}
537</pre>
538      </li>
539      <li>
540        <pre>
541if (x) {
542   // function expression
543   function world() {}
544}
545</pre>
546      </li>
547      <li>
548        <pre>
549// function statement
550function a() {
551   // function statement
552   function b() {}
553   if (0) {
554      // function expression
555      function c() {}
556   }
557}
558</pre>
559      </li>
560    </ul>
561    <h4 id="Conditionally_defining_a_function" name="Conditionall
>y_defining_a_function"> 
562      Conditionally defining a function
563    </h4>
564    <p>
565      Functions can be conditionally defined using function expre
>ssions or the <code>Function</code> constructor. 
566    </p>
567    <p>
568      In the following script, the <code>zero</code> function is 
>never defined and cannot be invoked, because '<code>if (0)</code> 
>' evaluates to false: 
569    </p>
570    <pre class="eval">
571if (0)
572   function zero() {
573      document.writeln("This is zero.");
574   }
575</pre>
576    <p>
577      If the script is changed so that the condition becomes '<co
>de>if (1)</code>', function <code>zero</code> is defined. 
578    </p>
579    <p>
580      Note: Although this looks like a function declaration, this
> is actually a function expression since it is nested within anot 
>her statement. See <a href="#Function_constructor_vs._function_de 
>claration_vs._function_expression">differences between function d 
>eclarations and function expressions</a>. 
581    </p>
582    <p>
583      Note: Some JavaScript engines, not including <a href="/ru/S
>piderMonkey" title="ru/SpiderMonkey">SpiderMonkey</a>, incorrectl 
>y treat any function expression with a name as a function declara 
>tion. This would lead to <code>zero</code> being defined, even wi 
>th the always-false conditional. A safer way to define functions  
>conditionally is to define the function anonymously and assign it 
> to a variable: 
584    </p>
585    <pre class="eval">
586if (0)
587   var zero = function() {
588      document.writeln("This is zero.");
589   }
590</pre>
591    <h3 id="Functions_as_event_handlers" name="Functions_as_event
>_handlers"> 
592      Functions as event handlers
593    </h3>
594    <p>
595      In JavaScript, <a href="/ru/DOM" title="ru/DOM">DOM</a> eve
>nt handlers are functions (as opposed to objects containing a <co 
>de>handleEvent</code> method in other DOM language bindings). The 
> functions are passed an <a href="/ru/DOM/event" title="ru/DOM/ev 
>ent">event</a> object as the first and only parameter. Like any o 
>ther parameter, if the event object does not need to be used, it  
>can be omitted in the list of formal parameters. 
596    </p>
597    <p>
598      Possible event targets in a <a href="/ru/HTML" title="ru/HT
>ML">HTML</a> document include: <code>window</code> (<code>Window< 
>/code> objects, including frames), <code>document</code> (<code>H 
>TMLDocument</code> objects), and elements (<code>Element</code> o 
>bjects). In the <a class="external" href="http://www.w3.org/TR/DO 
>M-Level-2-HTML/">HTML DOM</a>, event targets have event handler p 
>roperties. These properties are lowercased event names prefixed w 
>ith "on", e.g. <code>onfocus</code>. An alternate and more robust 
> way of adding event listeners is provided by <a class="external" 
> href="http://www.w3.org/TR/DOM-Level-2-Events/">DOM Level 2 Even 
>ts</a>. 
599    </p>
600    <p>
601      Note: Events are part of the DOM, not of JavaScript. (JavaS
>cript merely provides a binding to the DOM.) 
602    </p>
603    <p>
604      The following example assigns a function to a window's "foc
>us" event handler. 
605    </p>
606    <pre>
607window.onfocus = function() {
608   document.body.style.backgroundColor = 'white';
609};
610</pre>
611    <p>
612      If a function is assigned to a variable, you can assign the
> variable to an event handler. The following code assigns a funct 
>ion to the variable <code>setBGColor</code>. 
613    </p>
614    <pre>
615var setBGColor = new Function("document.body.style.backgroundColo
>r = 'white';"); 
616</pre>
617    <p>
618      You can use this variable to assign a function to an event 
>handler in several ways. Here are two such ways: 
619    </p>
620    <ol>
621      <li>scripting with DOM HTML event properties
622        <pre>
623document.form1.colorButton.onclick = setBGColor;
624</pre>
625      </li>
626      <li>HTML event attribute
627        <pre>
628&lt;input name="colorButton" type="button"
629   value="Change background color"
630   onclick="setBGColor();"/&gt;
631</pre>
632        <p>
633          An event handler set this way is actually a function, n
>amed after the attribute, wrapped around the specified code. This 
> is why the parenthesis in "<code>setBGColor()</code>" are needed 
> here (rather than just "<code>setBGColor</code>"). It is equival 
>ent to: 
634        </p>
635        <pre>
636document.form1.colorButton.onclick = function onclick(event) {
637   setBGColor();
638};
639</pre>
640        <p>
641          Note how the event object is passed to this anonymous f
>unction as parameter <code>event</code>. This allows the specifie 
>d code to use the Event object: 
642        </p>
643        <pre>
644&lt;input ...
645    onclick="alert(event.target.tagName);"/&gt;
646</pre>
647      </li>
648    </ol>
649    <p>
650      Just like any other property that refers to a function, the
> event handler can act as a method, and <code>this</code> would r 
>efer to the element containing the event handler. In the followin 
>g example, the function referred to by <code>onfocus</code> is ca 
>lled with <code>this</code> equal to <code>window</code>. 
651    </p>
652    <pre class="eval">
653window.onfocus();
654</pre>
655    <p>
656      A common JavaScript novice mistake is appending parenthesis
> and/or parameters to the end of the variable, i.e. calling the e 
>vent handler when assigning it. Adding those parenthesis will ass 
>ign the <em>value returned from calling the event handler</em>, w 
>hich is often <code>undefined</code> (if the function doesn't ret 
>urn anything), rather than the event handler itself: 
657    </p>
658    <pre class="eval">
659document.form1.button1.onclick = setBGColor();
660</pre>
661    <p>
662      To pass parameters to an event handler, the handler must be
> wrapped into another function as follows: 
663    </p>
664    <pre class="eval">
665document.form1.button1.onclick = function() {
666   setBGColor('some value');
667};
668</pre>
669    <h3 id="Backward_compatibility" name="Backward_compatibility"
>> 
670      Backward compatibility
671    </h3>
672    <h4 id="JavaScript_1.1_and_earlier" name="JavaScript_1.1_and_
>earlier"> 
673      JavaScript 1.1 and earlier
674    </h4>
675    <p>
676      You cannot nest a function statement in another statement o
>r in itself. 
677    </p>
678    <h3 id="Local_variables_within_functions" name="Local_variabl
>es_within_functions"> 
679      Local variables within functions
680    </h3>
681    <p>
682      <a href="/ru/Core_JavaScript_1.5_Reference/Functions/argume
>nts" title="ru/Core_JavaScript_1.5_Reference/Functions/arguments" 
>>arguments</a>: An array-like object containing the arguments pas 
>sed to the currently executing function. 
683    </p>
684    <p>
685      <a href="/ru/Core_JavaScript_1.5_Reference/Functions/argume
>nts/callee" title="ru/Core_JavaScript_1.5_Reference/Functions/arg 
>uments/callee">arguments.callee</a>: Specifies the currently exec 
>uting function. 
686    </p>
687    <p>
688      <a href="/ru/Core_JavaScript_1.5_Reference/Functions/argume
>nts/caller" title="ru/Core_JavaScript_1.5_Reference/Functions/arg 
>uments/caller">arguments.caller</a>: Specifies the function that  
>invoked the currently executing function. 
689    </p>
690    <p>
691      <a href="/ru/Core_JavaScript_1.5_Reference/Functions/argume
>nts/length" title="ru/Core_JavaScript_1.5_Reference/Functions/arg 
>uments/length">arguments.length</a>: Specifies the number of argu 
>ments passed to the function. 
692    </p>
693    <h3 id="Examples" name="Examples">
694      Examples
695    </h3>
696    <h4 id="Example:_Returning_a_formatted_number" name="Example:
>_Returning_a_formatted_number"> 
697      Example: Returning a formatted number
698    </h4>
699    <p>
700      The following function returns a string containing the form
>atted representation of a number padded with leading zeros. 
701    </p>
702    <pre class="eval">
703// This function returns a string padded with leading zeros
704function padZeros(num, totalLen) {
705   var numStr = num.toString();             // Initialize return 
>value as string 
706   var numZeros = totalLen - numStr.length; // Calculate no. of z
>eros 
707   for (var i = 1; i &lt;= numZeros; i++) {
708      numStr = "0" + numStr;
709   }
710   return numStr;
711}
712</pre>
713    <p>
714      The following statements call the padZeros function.
715    </p>
716    <pre class="eval">
717var result;
718result = padZeros(42,4); // returns "0042"
719result = padZeros(42,2); // returns "42"
720result = padZeros(5,4);  // returns "0005" 
721</pre>
722    <h4 id="Example:_Determining_whether_a_function_exists" name=
>"Example:_Determining_whether_a_function_exists"> 
723      Example: Determining whether a function exists
724    </h4>
725    <p>
726      You can determine whether a function exists by using the <c
>ode>typeof</code> operator. In the following example, a test is p 
>eformed to determine if the <code>window</code> object has a prop 
>erty called <code>noFunc</code> that is a function. If so, it is  
>used; otherwise some other action is taken. 
727    </p>
728    <pre>
729 if ('function' == typeof window.noFunc) {
730   // use noFunc()
731 } else {
732   // do something else
733 }
734</pre>
735    <p>
736      Note that in the <code>if</code> test, a reference to <code
>>noFunc</code> is used—there are no brackets "()" after the funct 
>ion name so the actual function is not called. 
737    </p>
738    <h3 id="See_also" name="See_also">
739      See also
740    </h3>
741    <p>
742      <a href="/ru/Core_JavaScript_1.5_Reference/Global_Objects/F
>unction" title="ru/Core_JavaScript_1.5_Reference/Global_Objects/F 
>unction">Function</a>, <a href="/ru/Core_JavaScript_1.5_Reference 
>/Statements/function" title="ru/Core_JavaScript_1.5_Reference/Sta 
>tements/function">function statement</a>, <a href="/ru/Core_JavaS 
>cript_1.5_Reference/Operators/Special_Operators/function_Operator 
>" title="ru/Core_JavaScript_1.5_Reference/Operators/Special_Opera 
>tors/function_Operator">function operator</a> 
743    </p>
744    <p>
745      {{ NeedsTechnicalReview() }}
746    </p>
747    <p>
748      {{ languages( { "en": "en/Core_JavaScript_1.5_Reference/Fun
>ctions", "ja": "ja/Core_JavaScript_1.5_Reference/Functions" } ) } 
>} 
749    </p>

Back to History