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, Delegation (stub) allows us replace a many similar functions by a single function.
When defining a function in JavaScript use
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
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
obj = {
'my_fn': function(arg1, arg2, arg3){
// Body of the function.
}
};
but this is often best avoided.
JavaScript provides another method (called function declaration)
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].
There are four ways of calling a function in JavaScript. The difference involves Functions and this, which we’ve not covered yet. In brief, the four forms are:
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.
This is the simplest form of function call.
x = my_fn(a, b, c);
The this-object is set to the Global object (stub), which causes a problem only if the body of the function refers to this. Many functions are intended to be used in this way.
This is the usual, but not the most general, way of setting the this-object.
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:
x = a.b.c.d.e.my_fn(a, b, c);
tmp = a.b.c.d.e
x = tmp.my_fn(a, b, c);
In JavaScript the two following calls are rarely equivalent:
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].
Suppose obj is a JavaScript object. Then
x = my_fn.call(obj, a, b, c);
is equivalent to
x = my_fn(a, b, c);
except that the this-object is set to obj (rather than the global object). For more see [link].
Suppose obj is a JavaScript object. Then
x = my_fn.apply(obj, [a, b, c]);
is equivalent to
x = my_fn(a, b, c);
except that the this-object is set to obj. For more see [link].
If obj is not a JavaScript object then in
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].