Categories
JavaScript Best Practices

JavaScript Best Practices — Defining Functions and Calling Them

Spread the love

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at how the best way to define functions in our JavaScript code and call functions with a variable number of parameters.

Never Use the Function Constructor to Create a New function

In JavaScript, the Function constructor lets us define a function with strings for parameters and the function body.

All arguments but the last arguments are parameters, which are passed in as strings. The last argument is the function body, which is also passed in as strings.

The Function constructor returns a function that runs in the global scope only.

For instance, we can define a function as follows:

const add = new Function('a', 'b', 'return a + b');

In the code above, we called the Function constructor with the parameters a and b , which are defined as strings, and the function body return a + b .

This is bad because everything is defined as strings, which means that they’re hard to trace and debug. Also, there’s a chance that someone may pass in malicious strings into the Function constructor so that malicious code may run.

All returned functions also run in the global scope, which is probably not what we want.

Therefore, we shouldn’t run any code that uses the Function constructor.

Spacing in a Function Signature

Spacing in a function signature should be standardized and consistent. There should be no space after the function keyword or the function name. And there should be one closing parentheses and the opening curly brace.

For instance, we should write something like the following code:

function() {}
function add() {}

This way, we can read the name easily and the parentheses are easily readable as well.

Never Mutate Parameters

Mutating parameters is always bad. Since objects are passed by reference, they also mutate the arguments that are mutated outside.

For instance, if we write the following code:

const foo = (a) => a.foo = 2;
let a = {
  foo: 1
};
foo(a);
console.log(a);

Then in the code above, we have the a parameter in our foo function. Inside the function, we set a.foo to 2.

Then when we define the variable a with:

{
  foo: 1
}

Next when we call foo(a) , then we get that a is {foo: 2} because we mutate the parameter, which is propagated to the a variable itself because a is passed in by reference to the foo function.

What we should do instead is that we should assign the property’s value variable inside the function and then mutate that.

For instance, we can do the following:

const foo = (a) => {
  let bar = a.foo;
  bar = 2;
};

let a = {
  foo: 1
};
foo(a);
console.log(a);

This way, we get that a is:

{
  foo: 1
}

which is what we passed in originally. In the code above, we assigned a.foo to bar and set the value of bar to 2.

Prefer the Use of the Spread Operator ... to Call Functions with Variable Number of Parameters

With the introduction of the spread operator, we can use it to call functions with a variable number of parameters by calling it with an array that’s spread into arguments of the method by the spread operator.

This is much better than the old way, which is to call apply on the function to call a function with a variable number of parameters.

For instance, we can call the Math.max method to get the maximum number from an array of numbers as follows:

const max = Math.max(...[1, 2, 3]);

In the code above, we called Math.max with an array by using the spread operator. The spread operator spreads the array [1, 2, 3] into the arguments of the Math.max method,

Then we get 3 as the result of max .

This is much better than the old way, which is to use apply as follows:

const max = Math.max.apply(undefined, [1, 2, 3]);

In the code above, we called apply with 2 arguments, the first argument is the value of this , which can be anything since it’s a static function, but we chose undefined . The 2nd argument is the array of arguments that we want to pass into Math.max .

And then we get the same result. As we can see, it’s more a more complex way to get the same result.

Conclusion

We should never use the Function constructor to create a function. Also, we should use the spread operator to call functions that take a variable number of arguments rather than apply .

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *