Mercurial > js4py
view source/functions.rst @ 213:0ea90a1819c2 default tip
Custom theming
| author | Radomir Dopieralski <radomir.dopieralski@allegro.pl> |
|---|---|
| date | Wed, 27 Jun 2012 16:35:54 +0200 |
| parents | 4e6cfa066d1a |
| children |
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].
