i dont understand this javascript return statment. its using this arrow function

Viewed 128

can anyone explain this javascript syntax. i dont understand that return statement. Is "person" an argument to the function? if 'yes', from where it is passing? there is no person variable in this component. At least an elaborated version of that return statement will also help. so that i can understand

const filterBy = (term) => {
    const searchTermLower = term.toLowerCase()
    return (person) => Object.keys(person).some(prop => 
        person[prop].toLowerCase().indexOf(searchTermLower) !== -1
    )
}
const filterPerson = persons.filter(filterBy(searchTerm))

here presons is an array of objects and search term is a string.

const persons=[
{ name: 'abc', number: '123456' },
{ name: 'def', number: '44233' },
{ name: 'xyz', number: '345345' },
{ name: 'npe', number: '12312' }]

later im using this returned filterPerson for later processing. code is runnin totally fine but this arrow function in return is what confusing me. im okay to update question if any more data is needed.

2 Answers

It is called higher-order function.

You have no issue understanding what this means right:

let increment = x => x+1;

Now imagine that you have a function, which instead of returning incremented value as above, returns another function, how would you write it? Simple:

let adder = x => y => y+x;

Usage:

let adder = x => y => y+x;
let add5 = adder(5);
console.log(add5(9));

This example also relies on concept of closure: x is a closure (notice how it is remembered when I call add5 with 9 and returns 14), that is a different topic, but shouldn't stop you from grasping what higher order function means.

Is "person" an argument to the function? if 'yes', from where it is passing?

Your person is same as y in my case. So when is y passed? Answer: When I invoke add5, and its value is 9.


To refer exactly to your example, you want to know what is person.

Example 1

Here:

[1,2,3].filter(person=>person)

What is value of person? 1,2,3 right?

Now replace function person=>person with this:

Example 2

let filterBy = ()=>person=>person; // Higher order function, just first function doesn't take a parameter
[1,2,3].filter(filterBy())

The difference between example 1 and example 2 is in example 1 I directly wrote the function, in example 2 I generated it by calling filterBy().

Well, it's just an alternative way of writing the following function in simplest terms:

const persons = [{
    name: 'abc',
    number: '123456'
  },
  {
    name: 'def',
    number: '44233'
  },
  {
    name: 'xyz',
    number: '345345'
  },
  {
    name: 'npe',
    number: '12312'
  }
];

const searchTerm = 'abc';
const filterPerson = persons.filter((person) => {
  const searchTermLower = searchTerm.toLowerCase();
  return Object.keys(person).some(prop => person[prop].toLowerCase().indexOf(searchTermLower) !== -1)
})

console.log(filterPerson);

If you notice carefully, I'm passing an anonymous function to the persons.filter function. So if I want to get all fancy, I can just write that anonymous function as a separate block and return that entire function to the persons.filter function for it to be called in multiple places in my code. Which is exactly what has been done in the snippet you posted in the question.

Here's me trying to be all fancy:

const persons = [{
    name: 'abc',
    number: '123456'
  },
  {
    name: 'def',
    number: '44233'
  },
  {
    name: 'xyz',
    number: '345345'
  },
  {
    name: 'npe',
    number: '12312'
  }
];

const myFunctionThatWasPreviouslyAnonymous = (term) => {
  const searchTermLower = term.toLowerCase()
  return (person) =>
    Object.keys(person)
    .some(prop => person[prop].toLowerCase().indexOf(searchTermLower) !== -1)

}

const searchTerm = 'abc';
const filterPersonFancy = persons.filter(myFunctionThatWasPreviouslyAnonymous(searchTerm));
console.log(filterPersonFancy)

Related