JS: Functions

Theory: Parameter destructuring

When we pass an argument when we call a function, its value is assigned to the function parameter. This is an implicit automatic assignment, because this operation is "not visible" in the code.

const func = (x) => {
  // the x parameter will be assigned to
  // argument value when the function is called
  console.log(x);
};

func(1); // => 1
// It can be imagined that
// the x parameter is created inside the function,
// to which the value of the argument is assigned:
// {
//   let x = 1;
//   console.log(x);
// };

func([1, 2]); // => [1, 2]
// An example of an array transfer:
// {
//   let x = [1, 2];
//   console.log(x);
// };

Passing an argument is no different from simply assigning a value to a variable. This means that we have access to destructuring right in the function definition.

Array destructuring

Let's write a function that takes as input an array of two elements and prints them to the terminal. Let's look at different ways of implementing parameter handling.

Not the most expressive variant - direct reference to array elements by indexes:

const func = (elements) => {
  console.log(elements[0]);
  console.log(elements[1]);
};

// let elements = [1, 2];
func([1, 2]);
// => 1
// => 2

A more interesting option is to destruct the array in the body of the function:

const func = (elements) => {
  const [first, second] = elements;
  console.log(first);
  console.log(second);
};

// let elements = [1, 2];
func([1, 2]);
// => 1
// => 2

But you can go even further and add destructuring right into the definition:

const func = ([first, second]) => {
  console.log(first);
  console.log(second);
};

// let [first, second] = [1, 2];
func([1, 2]);
// => 1
// => 2

All the standard rules of array destructuring apply:

const elements = [1, 2];

// let [first, second] = elements;
func(elements);
// => 1
// => 2

// let [first, second] = [1];
func([1]);
// => 1
// => undefined

// let [first, second] = [];
func([]);
// => undefined
// => undefined

If there are less than two elements in the passed array, the parameters that "lacked" the corresponding values will contain undefined. For such cases, you can insure and set a default value:

const func = ([first = 666, second = 777]) => {
  console.log(first);
  console.log(second);
};

// [first = 666, second = 777] = [1];
func([1]);
// => 1
// => 777

// [first = 666, second = 777] = [];
func([])
// => 666
// => 777

Destructuring of the object

Let's write a function that takes as input an object with information about the name and surname of a user and outputs it to the terminal. Immediately we implement the variant with destructuring of the object for parameters:

const func = ({ name, surname }) => {
  console.log(name);
  console.log(surname);
};

// let { name, surname } = { name: 'John', surname: 'Doe' };
func({ name: 'John', surname: 'Doe' });
// => John
// => Doe

A typical situation in practice is when an object with many properties comes to the input of a function, but in fact we do not need the values of all properties, but only a few. This can happen, for example, when processing an HTTP response from a server or configuration for a program. In such cases, we take away only the values we need - because we don't have to specify all of the object's properties when destructuring:

const func = ({ surname }) => {
  // take only surname values
  console.log(surname);
};

const obj = { name: 'John', surname: 'Doe' };

// let { surname } = { name: 'John', surname: 'Doe' };
func(obj); // => Doe

Recommended programs