Functions
A good function typically takes one or only a few parameters and returns an output. If you’re writing functions that need many many parameters, it might be a sign to split it up into smaller functions. Likewise if you can’t fit the code for the function on a single page of your editor: it probably ought to be made more digestable.
Two of the common ways you’ll see a function expressed in Javascript:
The first (somewhat old-school) style has the occasional benefit that you can call a function before it shows up in the source code.
The demos mostly prefer the second form, the so-called ‘fat arrow’ syntax. One reason is that it’s more succinct, and when the body of the function is a simple expression, you can do away with the { }
and return
as well:
When using functions as parameters to other functions, the preferred syntax is less cluttered, allowing you to see what’s going on more clearly.
There are some other advantages and disadvantages of the two function styles, but for the context of the ixfx demos, these don’t matter.
Parameters
When making a function, it probably ought to be taking some input.
Using type annotations, we can also suggest what kind of data the parameter should be. This helps when calling and writing the function, because your code editor will give you helpful warnings.
Multiple parameters can be listed with a comma, mirroring how they get passed to the function.
Parameters can also have default values. This makes it easier from the caller side, since it doesn’t have to provide values it doesn’t really ‘care’ about. Note the [ ]
around the parameter name in the type annotation to denote optionality.
A key rule about default parameters is they have to be on the far-right on the list of parameters. This won’t work as expected (and indeed VS Code will warn you about it):
Returning objects
One ‘gotcha’ with the fat arrow function style is if you return an object, it has to be enclosed in ( )
. That’s because the the { }
we need to define an object is ambiguous with the start and end of a function block.
This is not a problem with the old-school approach because the semantics are not ambigious. However, it remains more cluttered:
Returning functions
In Javascript and ixfx, it’s common for functions to return functions. This can certainly be hard to wrap your head around at times.
This technique is useful because we can ‘bake in’ parameters without having to pass them in each and every time.
A perfect example is interpolate. Let’s say we always want to interpolate values at the same rate. We’d have to repeat this parameter continually, or add it to something like settings:
One of the ways of calling interpolate
lets us bake in the amount:
This can be useful for DRY principles, but also the idea of encapsulation. Now we have a function that can interpolate with two inputs, which can be shared with other parts of your code without them needing to know how the interpolation happens. Only the code that creates the interpolation function needs to decide.
Maybe we set up our interpolate function once, as a setting, so it’s a reusable function later. In turn, this makes update()
simpler and more readable.
We could imagine a refactoring where angleInterpolate
instead computes a random value between the a
and b
values. The neat thing is we wouldn’t need to change update()
at all, since angleInterpolate
still has the same signature of (number, number) => number
.
If you find yourself calling a function repeatedly with the same parameters, you might want to write a little function that wraps it and passes in the standard parameter.
For example, you might have lots of:
A little helper function could be:
Which you can then then use with:
If it ends up saving you some typing and making your code more readable, it might be worth it, even for such trivial cases.
If you end up with a few of these, can stash them away in a separate file to be imported and shared:
On objects
Functions can ‘hang’ off objects. This is a great way of grouping functions together.
This is essentially what happens when we import as a module: