Pre-closures post

Pete Griffith
3 min readFeb 23, 2021

A lot of my heavy thinking now is to try to understand closures, and writing higher order functions in general. There’s something there that isn’t perfectly clicking, so I thought I might try to write out what I do feel comfortable with and go from there.

I’m comfortable using and understanding methods. For whatever reason it makes sense that arrays come with functions that can traverse and manipulate them, and the .map and .filters of the world don’t particularly bug me although they take functions as arguments. I’m relatively comfortable even with .reduce. I think I’m also ok with writing functions that take functions as arguments.

In a problem set from yesterday, I recognized that writing a function that outputs an object on which I write methods isn’t particularly a stretch either. For whatever reason, including output functions as long as they’re attached to an object clarifys things.

What’s particularly frustrating is wrapping my head around functions that output pure functions, especially concerning inputs. I can understand how basic ones work (square()) and can work my self through writing them from scratch, but I don’t fully grok them yet.

As such, the concept of closures is still a bit tricky. I hope to get over that in the next few days of study.

— — — — — — — — — — — — — — — — — — — — — — —

NOTES

Yesterday I was working on a function to take an array and spit out a new array of unique elements from the first one. I was humming along and got it to work pretty simply using .includes() only to discover that native methods weren’t allowed and for the moment I had to come up with a more basic method. I considered using Set, but I wanted to understand how to build a unique function without any special new gadgets, so on the advice of a classmate from the Slack chat, I decided to build a “checker” object that loads up array elements and turns on a “true” light but does nothing for duplicate elements. That worked really well! Here’s the code:

_.uniq = (array) => {
// build checking object
const checker = {};
for (let i = 0; i < array.length; i++){
checker[array[i]] = true
}
//initialize and iterate checking if elements are true in the checker
const result = [];
for (let i = 0; i < array.length; i++) {
if (checker[array[i]] === true) {
result.push(array[i])
checker[array[i]] = false;
}
}
return result
};

(I hope I’ve posted a code snippet properly, formatting is annoying.)

I got some really good best practice notes for this code, which I want to respond to here.

  • ‘checker’ is maybe not the typical term, I would usually call this a ‘lookup’, like a lookup table. I would avoid using verb-names for things that aren’t functions. Verb-names are typically for functions, and an object would get more of a noun-type variable name. Love love love this kind of syntax correction. Nouns and verbs — things I already know and understand!
  • You can just say if (checker[array[i]]), you don't need the === true part. Yep, duh. Should have gotten that one.
  • You may want to use a for-of loop instead of a regular for-loop, because you aren’t using the index except to access the value. This is really personal preference more than best practices, but it’s something to think about. Totally true and I much prefer to use for-of or for-in loops. I think I had been using regular for loops out of necessity for a couple of problems and I used another one here out of habit.
  • Using Set is the more modern way to do this. There’s nothing wrong with using a lookup, but if you want to be newfangled you should use Set. This is on my list.
  • If you do want to do it the lookup way, you could condense your logic into one loop like this:
_.uniq = (array) => {
const lookup = {};
const result = [];
for (let item of array) {
if (!lookup[item]) {
result.push(item);
lookup[item] = 1;
}
}
return result;
};

Love it.

IN CONCLUSION

Time to circle back and really understand closures.

--

--