Should you pass the whole object to a function?
We communicate with functions through their parameters. The shorter and the more stable the parameter list is, the easier to change your code will be.
Let's say you have a function called sendPostToSubscribers
to send your latest post to your subscribers via email. A common question you might ask yourself when defining the parameters for that function is should I pass the whole post object to it or only the fields included in the email?
This actually depends on multiple factors—which I'll explain in this article.
When to send the whole object
Here are the two options we have in the above example:
function sendPostToSubscribers(post) {
// send the post using the post parameter
}
function sendPostToSubscribers(title, date, postUrl) {
// send the post using the above parameters
}
For this example, it's better to send the whole object for two reasons:
- Including a new post field to the email doesn't require you to update the parameter list.
- Deriving some extra data from the post can go to the post object instead of computing it each time you call the function.
Examples will explain the above two points better—so keep reading.
Including a new post field
If you want to include a new post field in the email using the second function version, you have to add a new parameter to the function. So if, for example, you want add an excerpt to it, you'll do this:
function sendPostToSubscribers(title, date, postUrl, excerpt) {}
After adding this new parameter, then you have to update every place that calls this function.
On the other hand, the parameter list for the whole-object function version will remain the same.
Reducing the number of updates after a certain update in the code is always better because it will reduce the number of bugs that can happen. Not only that, but also when sending the whole object, the parameter list doesn't grow—short parameter list makes the function easier to understand.
Keep related behavior inside the parameter object
The postUrl
in the second function version should contain the url of the post. Sometimes the post url is not stored in the database; it's instead computed dynamically by combining the site base url with a slug version of the title.
const postUrl = 'https://yoursite.com/blog/' + slugify(post.title)
If that logic is not stored in the post object, then you need to compute the url every time you need to call sendPostToSubscribers
. And that can lead to code duplication.
But sending the whole object lets you think about including that logic into the object itself. So, for this example you will include postUrl
into the post object—if it isn't already.
Moving code to the related object unfolds a number of great benefits, like encapsulation and easy testing.
When to send individual values
Should you always send the whole object? Of course not. There are cases where it's better to send individual values.
As a rule of thumb, the more generic your function is, the more likely you will send individual values.
Let's say you have a function called slugify
that turns some text into a slug version. For example, if you have the title "A Test Blog Post", it will become "a-test-blog-post".
It's very likely that the only place you will use it is when converting the post title into a slug. But that doesn't mean it should take the post object.
If you tie that function to a post, then you can't reuse it for other text. But these kind of functions are usually defined as utility functions that can be used, not only in the same project, but across multiple projects.
So, defining it like this:
function slugify(text) {}
Is better than this:
function slugify(post) {}
Also, defining this function for the whole post object doesn't give us the benefits we got in the previous example. For example, the slugify
parameter list is unlikely to change in the future because its whole job is just to convert strings.
What to do when your project does not have an object to pass?
In the first example, we already have an object (post) to pass. But in other cases, you might not have such an object; so instead you might be passing a number of individual parameters that can be grouped together. Grouping them can give you a lot of opportunities to improve your code—same benefits I showed you in this article.
If you are interested in reading more about this, I've already written an article about that: Introduce Parameter Object.