In basic terms, the nested functions/variables continue to live even when the outer function has completed its execution is closure.
Lets have an example for both Ruby and Javascript
Ruby
def ruby_m
x1 = 100
proc{ x1 = x1 + 1; puts x1 }
end
puts x1 # NameError: undefined local variable or method `x1'
m1 = ruby_m
m1[] # 101
m1[] # 102
m1[] # 103
.
.
.
You can see that the variable x1 binds in the block and you can play around the variable’s value even from outside the method.
Brief Description: First we store the proc (return statement of ruby_m) in m1. The proc basically contains the scope of x1 in it.
Then when we try to execute the proc from outside the method, and the value of x1 is first increased to 101 and assigned back in x1 and then we print value.
Now in the proc block, the value of x1 is updated to 101 i.e now when you execute the proc, you can see the value of x1 as 101. That’s what basically happens when we execute the m1[] second time. The value updates from 101 to 102 and print on the console.
And the same process goes like this.
Javascript
function js_func() {
let x1 = 100
return function(){
x1 = x1 + 1
console.log(x1)
}
}
func1 = js_func()
func1() // 101
func1() // 102
func1() // 103
.
.
.
The explanation is same for the this example as well that the value of x1 binds in the returned function from js_func function and you can simply play around with it’s value from outside the function.
Thanks for reading. :)