JavaScript Interview Questions. Closures

in #programming7 years ago (edited)

It's going to be a pretty short article with my thoughts and little notes about closures in JavaScript. And the first thing that has to be mentioned is that closures are common question on the interviews, so I want to pay much attention here.

1. What the heck are CLOSURES?

A closure is the combination of a function and the lexical environment within which that function was declared.

And what does it means?

const monkey = () => {
    const name = "Choop"
    return () => console.log(`My name is ${name}`)
}

const monkeyGreetings = monkey()
monkeyGreetings()

The monkey function here creates local variable called name and returned a function that uses this local variable. That means, we could get access to this local variable only by using returned function. And this is the first and the most obvious using of closures.
Let's make our code a bit harder:

const monkey = () => {
    let name = 'Sally'

    const setName = newName => name = newName
    const getName = () => name

    return {
        setName,
        getName
    }
}

const monky = monkey()
console.log(monky.getName()) // Sally
monky.setName('Bob')
console.log(monky.getName()) // Bob

Here we see something very familiar if you have come from OOP languages. In this example, as before, I created monkey function with monkey's name inside. And we do not have any access to change monkey's name direct, what is really important. We could say that name was encapsulated. And what we have in exchange is interfaces to mutate name var.

“Program to an interface, not an implementation.”
Design Patterns: Elements of Reusable Object Oriented Software

2. Where I can use it?1) Data privacy. JavaScript itself doesn't provide the ability to declare methods as either private or public. But, as we saw in the previous example, with closures we could emulate this functionality.
2) Function factories. One more way to use closures is to use outer function as a factory to creating functions with specific functionality. Just look below:

// create 'monkey' factory
const monkey = job => name => `${name} is ${job}`
// factory for monkey coders
const monkeyCoder = monkey('Programmer')

const Valera = monkeyCoder('Valera')
const John = monkeyCoder('John')
console.log(John) // John is Programmer

3) Partial Applications. Partial Application is a function that takes a function with multiple parameters and returns a function with fewer parameters. On the first look it may seems like a factory function, but here we pass function inside the factory. In such way we can create more reusable code. Again, lets look on an example below:

const partialApply = (fn, ...firstPartOfArgs) =>
    (...secondPartOfArgs) =>
        fn.apply(this, firstPartOfArgs.concat(secondPartOfArgs))

// here I again use monkey examples, that simply because information about monkeys very very often used in Enterprise-grade programming
const helloMonkey = (job, name) => `${name} is ${job}`
const monkeyCoder = partialApply(helloMonkey, 'Programmer')
const Valera = monkeyCoder('Valera')
console.log(Valera) // Valera is Programmer

Here you have to pay attention on firstPartOfArgs array and helloMonkey function, because this data play role of fixed parameters inside the closure scope. If you want to get more about Partial Applications, you can read article by Eric Eliot Curry or Partial Application?That's all for now.Happy coding.