An Interest In:
Web News this Week
- March 23, 2025
- March 22, 2025
- March 21, 2025
- March 20, 2025
- March 19, 2025
- March 18, 2025
- March 17, 2025
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 obj.foo // 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: https://dev.to/silvestricodes/encapsulate-and-moderate-with-closures-3734

Dev To

More About this Source Visit Dev To