Mercurial > js4py
view source/functions.rst @ 162:77e87f1b5811 core-javascript
$ hg merge core-javascript.closure-exercises # done, at least for now
| author | jf3243 |
|---|---|
| date | Wed, 09 Nov 2011 17:00:38 +0000 |
| parents | b76dbf891f88 |
| children | 4e6cfa066d1a |
line wrap: on
line source
Functions ========= A function contains code, possibly with parameters, that is stored for later use. In both JavaScript and Python, functions are first-class objects. This means that identifiers can have a function as their value, and be used as the parameter or return value of a function. It's common, when writing JavaScript for web pages, to create a large number of anonymous (nameless) and similar event-handing functions, one for each node. Often, :doc:`delegation` allows us replace a many similar functions by a single function. Defining a function ------------------- When defining a function in JavaScript use .. code-block:: javascript var my_fn = function(arg1, arg2, arg3){ // Body of the function. }; as the template, where of course you get to choose the number and names of the parameters. Unlike Python, you can't provide default values for the arguments, nor can you provide **\*args** and **\*\*kwargs**. However, as we will see, there is the pseudo-variable *arguments* in JavaScript. This template can be adapted .. code-block:: javascript obj.my_fn = function(arg1, arg2, arg3){ // Body of the function. }; to define an attribute or method of an object. This is most commonly done when *obj* is a prototype. You can also put a function in an object literal, as in .. code-block:: javascript obj = { 'my_fn': function(arg1, arg2, arg3){ // Body of the function. } }; but this is often best avoided. JavaScript provides another method (called function declaration) .. code-block:: javascript function my_fn(arg1, arg2, arg3){ // Body of the function. }; which should (in the author's view) never be used. It has strange properties [link]. .. _calling-a-function: Calling a function ------------------ There are four ways of calling a function in JavaScript. The difference involves :doc:`functions-and-this`, which we've not covered yet. In brief, the four forms are: .. code-block:: javascript x = my_fn(a, b, c); // Simple function call. x = obj.my_fn(a, b, c); // Method call. x = my_fn.call(obj, a, b, c); // Explicit this call. x = my_fn.apply(obj, [a, b, c]); // Explicit this apply. For all forms of the function call, supplying the wrong number of arguments **does not raise an error**. Instead, excess arguments are ignored, and excess parameters are initialised to *undefined*. Function call ^^^^^^^^^^^^^ This is the simplest form of function call. .. code-block:: javascript x = my_fn(a, b, c); The this-object is set to the :doc:`global-object`, which causes a problem only if the body of the function refers to *this*. Many functions are intended to be used in this way. Method call ^^^^^^^^^^^ This is the usual, but not the most general, way of setting the this-object. .. code-block:: javascript x = obj.my_fn(a, b, c); // Usual form. x = obj['my_fn'](a, b, c); // Variant form. The two forms are completely equivalent. The this-object is set to the *obj*. The two following calls are always equivalent: .. code-block:: javascript x = a.b.c.d.e.my_fn(a, b, c); tmp = a.b.c.d.e x = tmp.my_fn(a, b, c); Method call gotcha ^^^^^^^^^^^^^^^^^^ In JavaScript the two following calls are rarely equivalent: .. code-block:: javascript x = obj.my_fn(a, b, c); tmp = obj.my_fn x = tmp(a, b, c); whereas in Python they always are. For JavaScript, in the first the this-object is *obj* while in the second it is the global-object. For explanation see [link]. Explicit this-call ^^^^^^^^^^^^^^^^^^ Suppose *obj* is a JavaScript object. Then .. code-block:: javascript x = my_fn.call(obj, a, b, c); is equivalent to .. code-block:: javascript x = my_fn(a, b, c); except that the this-object is set to *obj* (rather than the global object). For more see [link]. Explicit this-apply ^^^^^^^^^^^^^^^^^^^ Suppose *obj* is a JavaScript object. Then .. code-block:: javascript x = my_fn.apply(obj, [a, b, c]); is equivalent to .. code-block:: javascript x = my_fn(a, b, c); except that the this-object is set to *obj*. For more see [link]. Explicit this gotcha ^^^^^^^^^^^^^^^^^^^^ If *obj* is not a JavaScript object then in .. code-block:: javascript x = my_fn.call(obj, a, b, c); x = my_fn.apply(obj, [a, b, c]); the this-object is set to the global object (which is probably not what you want). For more see [link].
