1

I've been reading through an article titled Don’t Be Scared Of Functional Programming and there is a piece of code I'm having trouble understanding (pasted below). The code's purpose is to get an item from an array of objects called data. What I don't understand is how the function within the function works. Where is the item argument coming from when you invoke getItem()?

var data = [
  { 
    name: "Jamestown",
    population: 2047,
    temperatures: [-34, 67, 101, 87]
  },
  {
    name: "Awesome Town",
    population: 3568,
    temperatures: [-3, 4, 9, 12]
  }
  {
    name: "Funky Town",
    population: 1000000,
    temperatures: [75, 75, 75, 75, 75]
  }
];


function getItem(propertyName) {
  // Return a function that retrieves that item, but don't execute the function.
  // We'll leave that up to the method that is taking action on items in our 
  // array.
  return function(item) {
    return item[propertyName];
  }
}

I Understand that JS allows functions to be passed as arguments because they are treated as “first-class objects" in JS, but I don't understand where that item argument would be coming from.

craig
  • 47
  • 6
  • Just like any other function, it comes from the invocation of the function. –  Dec 24 '15 at 16:22
  • Possible duplicate of [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Grundy Dec 24 '15 at 17:14

2 Answers2

3

This is defining a function that will accept a parameter called item which can be used to return the propertyName element from the given item. It is the function that is then passed back to the caller of getItem. It would be used as follows:

var getName = getItem('name');
var result = getName(x);

Where x is a variable containing a property called 'name'

Steve Harris
  • 5,014
  • 1
  • 10
  • 25
  • But how do you give the inner function the `item` parameter to accept when you're calling `getItem()`? Don't you just have `getItem()` and then whatever `propertyName` you're trying to get when calling `getItem()`? I'm not seeing how you can provide the `item` parameter within the inner function. – craig Dec 24 '15 at 16:23
  • 2
    IMO the example would be better to understand if you renamed `getSomething` to `getName` – user16538 Dec 24 '15 at 16:26
  • 1
    @craig in the example, I am calling the inner function as it has now been assigned to the var 'getName' with the propertyName 'name'. So getName(x) calls the inner function passing x to be used as the item. – Steve Harris Dec 24 '15 at 17:24
1

Maybe this helps a bit.

It utilized a partial application of the first parameter propertyName with Function.prototype.bind():

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

Small example with your data and function:

function getItem(propertyName, item) {
    return item[propertyName];
}

var data = [{ name: "Jamestown", population: 2047, temperatures: [-34, 67, 101, 87] }, { name: "Awesome Town", population: 3568, temperatures: [-3, 4, 9, 12] }, { name: "Funky Town", population: 1000000, temperatures: [75, 75, 75, 75, 75] }],
     // this returns a function with only item as parameter
    getName = getItem.bind(null, 'name');

document.write('<pre>' + JSON.stringify(data.map(getName), 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392