Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 6, 2019 06:19 pm GMT

Encapsulate and Moderate with Closures

Have you ever found yourself wanting to modify and update a data structure throughout the life of your application? Take the following code:

const obj = {}const modifyObj = (key, value) => {  obj[key] = value  return obj}modifyObj('foo', 'bar') // Returns { foo: 'bar'}modifyObj('biz', 'baz') // Returns { foo: 'bar', biz: 'baz' }

We have some object, obj, defined in our global scope, and a function, modifyObj that can accept a key/value pair that are assigned to the global object. We can see what happens when we invoke our function via the provided comments.

Given how our function is constructed and where our modified object is defined, is there anything that prevents us from directly interacting with the object outside of our function?

The answer is no:

delete // Yup I can do this!// Or...obj['foo'] = 'biz' // Totally valid - this is what our modifying function does!

This is not ideal. We really would like for an object that we can modify, but we'd also like to do so without exposing the object to the global scope. We can achieve this with closure!

Closures leverage what is known as a higher order function - a function that returns a function - to encapsulate variables and other data within a private scope. The returned function can access and modify that data, known as creating closure around it.

What this means is, we can create our object within the context of a higher order function, and then modify it without exposing that to the global scope. Let's take a look at the code.

const higherOrderFunc = () => {  const obj = {}  return function modifyObj(...args) {    const [key, value] = args    obj[key] = value    return obj  }}const modifyObj = higherOrderFunc()modifyObj('foo', 'bar') // Returns { foo: 'bar'}modifyObj('biz', 'baz') // Returns { foo: 'bar', biz: 'baz' } !!!console.log(obj) // ReferenceError: obj is not defined!// And I have no method of messing with the object from the outside!

Let's also walk through our code and talk about what's happening.

const higherOrderFunc = () => {  const obj = {}  return function modifyObj(...args) {    const [key, value] = args    obj[key] = value    return obj  }}

This is our closure. We create a higher order function that returns an inner function which retains knowledge of the outer obj variable. That way, we can invoke our function to modify the obj.

const modifyObj = higherOrderFunc()

Here, we invoke our higher order function to create our object and provide us with a setter function. Nothing has been done to the object quite yet.

modifyObj('foo', 'bar') // Returns { foo: 'bar'}modifyObj('biz', 'baz') // Returns { foo: 'bar', biz: 'baz' }

We operate on our object with our closure, and can see that the object updates as expected!

console.log(obj) // ReferenceError: obj is not defined!

Finally, we try to log the object outside of our closure's scope. We'll get a reference error, which means we are trying to operate on a variable that does not exist in our current scope!

Hopefully you can find some use for closures in your current or upcoming work. Can you think of some uses for it right now? We'll be discussing one in my next post and how powerful closure is in that context.

BONUS: My function only allows for setters. But there's a way to extend the higher order function to also return a getter so we can check our object. Feel free to provide your solution in the comments below!

Original Link:

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To