Structuring Lua classes - class

I'm constructing a class in Lua that has a number of groups of related functions within it, but am unsure whether there's a better way to structure it. I currently have to develop for a Lua 5.1 environment but am hopeful that Lua 5.3 will be possible in the near future.
The class will be used in a number of different Lua programs, so I want something I can just drop in as a single chunk of code (the environment I'm programming for means that modules and require aren't and won't be an option).
Ideally I want a black box piece of code (except for the exposed public methods) and not to duplicate code in different classes (to improve maintainability).
What I have at present is (generalised):
function Fclass()
--here I declare a bunch of local functions that can be called by any of the public methods
local function A(parms)
end
--Public methods set 1
--here I declare a bunch of state variables shared by BSelector and GetB
local BSelector = function()
A(parmvalues)
--returns a bunch of iup controls with supporting (complicated) logic
end
local GetB = function()
--returns the values of the iup controls created in Bselector
end
--Public methods set 2
--here I declare a bunch of state variables shared by DSelector and GetD
local DSelector = function()
--returns a bunch of iup controls with supporting (complicated) logic
end
local GetD = function()
A(parmvalues)
--returns the value of the iup controls created in Dselector
end
return{BSelector =BSelector , GetB =GetB, DSelector =DSelector , GetD =GetD}
end
The "B" and "D" groups of methods are totally independent except they both use the local functions "A" etc. (which don't depend on external variables); their state variables ideally should be local to the group.
Is this a sensible structure? Or should I be splitting the "B" and "D" groups into two separate classes and either duplicating the local functions or dropping them in as a separate piece of code? I don't really want to expose the local functions outside the classe(es) because there will inevitably be naming conflicts... Most programs will use all the groups of methods, although there will be some that only use a single group.
Or is there a better way to do this?
I'm invoking them thus:
myB = Fclass()
myD = Fclass()
someresults = myB.Bselector()
otherresults = myD.Dselector()
Updated to add: I'm advised I may not be using the terminology properly and what I'm doing isn't classes. My approach is based on Programming in Lua and was selected because I wanted to keep the state variables for the class? object? private -- not accessible except via the public methods.

In your example, it seems you encapsulate the state of your instances through closures, not table values.
While this has the advantage of stronger encapsulation, as upvalues are invisible from the outside without using the debug library, it also comes with the disadvantage that Lua has to close each method for each instance, wasting some more memory (not a lot though).
Another benefit is that when instance variables are implemented as table fields, they need not be declared before the method, as table indexing is string-based, whereas when implemented as closures, the local varaible needs to be known before the function is defined (this also applies to other methods, which in either implementation work the same way as instance variables).
It's more common to store instance variables as table values inside the object, and passing the object as a first argument to the functions. There's even syntactic sugar for this.
There's lots of ways for doing classes in Lua, with many different tradeoffs (some are better at inheritance, while others perform better, etc.)
Since you don't seem to need any inheritance, you can go with a simple factory function, as you're pretty much doing already.
The way I personally like to build such factory functions is:
local object do
local class = {}
local meta = {__index=class} -- Object metatable
function class:print() -- A method of the class
print("Hello, I am an object and my x is " .. tostring(self.x))
end
function object(self) -- The factory function for the Class
self.x = self.x or 0
return setmetatable(self, meta)
end
end
local o = object {
x = 20
}
o:print()
o.x = 30
o:print()
This has the benefit that, for classes with many methods and many instances, the methods aren't copied into every instance, which saves some memory.
Alternatively, you can do something like this
local object do
local function object_print(self)
print("Hello, I am an object and my x is " .. tostring(self.x))
end
function object(self)
self.x = self.x or 0
self.print = object_print -- Store method directly in the object
return self
end
end
Again, this saves a reference to every method in every instance, wasting some memory. The benefit is that you can now think of classes as traits. When you write
person { name = "henry" }
You can think of it as creating a new person with the name Henry, but you can also think of it as creating an object with the name Henry and adding the person trait to it.
Because of this benefit of combining two concepts of OOP into one implementation and not having any pesky inheritance, it's my favourite way of building objects in Lua in most simple cases.
Update
The trait approach also lends itself to defining several classes/traits together:
local person, human do
-- Some generic method shared by both classes
local function object_get_name(self)
return self.name
end
-- Person uses this as a method, but human uses
-- it as a function through an upvalue. Both work,
-- but have different upsides and downsides.
-- A method of person
local function person_say_hi(self)
print(self:get_name() .. " says hi!")
-- Calling get_name as a method here
end
-- A method of human
local function human_describe(self)
print(object_get_name(self) .. ' is a human!')
-- Calling get_name as an upvalue
end
function person(self)
self.name = self.name or 'A person'
self.say_hi = person_say_hi
self.get_name = object_get_name
-- Needs to be a method because person_say_hi assumes it to be one
return self
end
function human(self)
self.name = self.name or 'A human'
self.describe = human_describe
return self
end
end
-- Create a new person
local henry = person{ name = "Henry" }
henry:say_hi()
-- Create a new human
local steve = human { name = "Steve" }
steve:describe()
-- Change the way henry gets his name
function henry:get_name()
return self.name:upper()
end
-- This only affects henry; all other "person" objects keep their old
henry:say_hi()
-- This only works because say_hi accesses the method
-- Add the person trait to steve
person(steve)
steve:describe() -- Steve is still a human
steve:say_hi() -- Steve is also a person now

Some years ago I built myself a superclass for basic OOP functionality in Lua.
Usage:
Person = LuaObject:extend({
__name = "Person",
name = "",
age = 0,
})
-- constructor
function Person:new(name, age)
Person.__super.new(self)-- calling the super constructor
self.name = name
self.age = age
end
function Person:getName()
return self.name
end
function Person:getAge()
return self.age
end
Feel free to use it:
--[[
LuaObject for basic OOP in Lua
Lua 5.0
]]
local function newIndexFunction(tbl, name, value)
if name == "new" and type(value) == "function" then
local constructor = value
rawset(tbl, name, function(self, ...)
local object = self
if object.__class == nil then
object = {}
object.__class = self
object.__id = string.sub(tostring(object), 8)
self.__index = self
setmetatable(object, self)
end
constructor(object, unpack(arg))-- Lua 5.0
-- constructor(object, ...)-- Lua 5.1+
return object
end)
else
rawset(tbl, name, value)
end
end
local function toStringFunction(tbl)
return tbl:toString()
end
LuaObject = {__name = "LuaObject"}
setmetatable(LuaObject, {__newindex = newIndexFunction, __tostring = toStringFunction})
function LuaObject:extend(class)
class = class or {}
self.__index = self
self.__newindex = newIndexFunction
self.__tostring = toStringFunction
local constructor = nil
if class.new ~= nil then
constructor = class.new
class.new = nil
end
setmetatable(class, self)
if constructor ~= nil then
class.new = constructor
end
class.__super = self
return class
end
function LuaObject:new()
end
function LuaObject:getSuperClass()
return self.__super
end
function LuaObject:getClass()
return self.__class
end
function LuaObject:toString()
return string.format("[%s] %s", self.__class.__name, self.__id)
end
function LuaObject:isInstance(value)
return value ~= nil and type(value) == "table" and getmetatable(value) == self
end
--[[
-- examples
-- basic class
Person = LuaObject:extend({
__name = "Person",
name = "",
age = 0,
})
-- constructor
function Person:new(name, age)
Person.__super.new(self)-- calling the super constructor
self.name = name
self.age = age
end
function Person:getName()
return self.name
end
function Person:getAge()
return self.age
end
-- extending classes
Customer = Person:extend({
__name = "Customer",
id = 0,
})
function Customer:new(id, name, age)
Customer.__super.new(self, name, age)
self.id = id
end
function Customer:getID()
return self.id
end
-- overriding methods
function Customer:getName()
-- calling super methods
local realResult = Customer.__super.getName(self)
if string.len(realResult) <= 5 then
return realResult
else
return string.sub(realResult, 1, 5)
end
end
-- testing
local customer1 = Customer:new(1, "rollback", 19)
local customer2 = Customer:new(2, "Kori", -1)
print(assert(customer1:getName() == "rollb", "Overriding of getName failed"))
print(assert(customer2:getName() == "Kori", "Overriding of getName failed"))
print(assert(customer1:getID() == 1, "Error in getID"))
print(assert(customer1:getAge() == 19, "Error in getAge"))
print(customer1)
]]

You can create 2 up-values for your class functions. the 1st value holds public variables that will be accessed by your class' caller, such as the functions themselves and any caller handled options.
while the 2nd will be for your private values those that are only known and accessible from within the class. You can use this private table to store internal state or other inner workings that will not be exposed to the caller.
function class(first, second)
local public = {first}
local _private = {second}
function _private.A(parms)
--private function not available outside of class.
end
function public:selector() -- public class available to caller
_private.A(parmvalues) -- calls private class
end
function public:get()
return _private[1]
end
return public
end
myB = class('hello', ' world!') --passing in a variable for public, and one for private.
myD = class('hello...', ' world?')
print(myB[1] .. myB:get()) --get a public value, and uses get function to retrieve private value
print(myD[1] .. myD:get())
Additionally if the class functions should never be changed by your user, you can enforce that by changing return public to:
local meta = {
__index = public,
__newindex = function(t, k, v)
error("this table is read-only")
end,
__metatable = false
}
return setmetatable({}, meta) -- this make the public table read only

Related

how to set text in mouseover array leaflet [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
How would you explain JavaScript closures to someone with a knowledge of the concepts they consist of (for example functions, variables and the like), but does not understand closures themselves?
I have seen the Scheme example given on Wikipedia, but unfortunately it did not help.
A closure is a pairing of:
A function and
A reference to that function's outer scope (lexical environment)
A lexical environment is part of every execution context (stack frame) and is a map between identifiers (i.e. local variable names) and values.
Every function in JavaScript maintains a reference to its outer lexical environment. This reference is used to configure the execution context created when a function is invoked. This reference enables code inside the function to "see" variables declared outside the function, regardless of when and where the function is called.
If a function was called by a function, which in turn was called by another function, then a chain of references to outer lexical environments is created. This chain is called the scope chain.
In the following code, inner forms a closure with the lexical environment of the execution context created when foo is invoked, closing over variable secret:
function foo() {
const secret = Math.trunc(Math.random() * 100)
return function inner() {
console.log(`The secret number is ${secret}.`)
}
}
const f = foo() // `secret` is not directly accessible from outside `foo`
f() // The only way to retrieve `secret`, is to invoke `f`
In other words: in JavaScript, functions carry a reference to a private "box of state", to which only they (and any other functions declared within the same lexical environment) have access. This box of the state is invisible to the caller of the function, delivering an excellent mechanism for data-hiding and encapsulation.
And remember: functions in JavaScript can be passed around like variables (first-class functions), meaning these pairings of functionality and state can be passed around your program: similar to how you might pass an instance of a class around in C++.
If JavaScript did not have closures, then more states would have to be passed between functions explicitly, making parameter lists longer and code noisier.
So, if you want a function to always have access to a private piece of state, you can use a closure.
...and frequently we do want to associate the state with a function. For example, in Java or C++, when you add a private instance variable and a method to a class, you are associating the state with functionality.
In C and most other common languages, after a function returns, all the local variables are no longer accessible because the stack-frame is destroyed. In JavaScript, if you declare a function within another function, then the local variables of the outer function can remain accessible after returning from it. In this way, in the code above, secret remains available to the function object inner, after it has been returned from foo.
Uses of Closures
Closures are useful whenever you need a private state associated with a function. This is a very common scenario - and remember: JavaScript did not have a class syntax until 2015, and it still does not have a private field syntax. Closures meet this need.
Private Instance Variables
In the following code, the function toString closes over the details of the car.
function Car(manufacturer, model, year, color) {
return {
toString() {
return `${manufacturer} ${model} (${year}, ${color})`
}
}
}
const car = new Car('Aston Martin', 'V8 Vantage', '2012', 'Quantum Silver')
console.log(car.toString())
Functional Programming
In the following code, the function inner closes over both fn and args.
function curry(fn) {
const args = []
return function inner(arg) {
if(args.length === fn.length) return fn(...args)
args.push(arg)
return inner
}
}
function add(a, b) {
return a + b
}
const curriedAdd = curry(add)
console.log(curriedAdd(2)(3)()) // 5
Event-Oriented Programming
In the following code, function onClick closes over variable BACKGROUND_COLOR.
const $ = document.querySelector.bind(document)
const BACKGROUND_COLOR = 'rgba(200, 200, 242, 1)'
function onClick() {
$('body').style.background = BACKGROUND_COLOR
}
$('button').addEventListener('click', onClick)
<button>Set background color</button>
Modularization
In the following example, all the implementation details are hidden inside an immediately executed function expression. The functions tick and toString close over the private state and functions they need to complete their work. Closures have enabled us to modularize and encapsulate our code.
let namespace = {};
(function foo(n) {
let numbers = []
function format(n) {
return Math.trunc(n)
}
function tick() {
numbers.push(Math.random() * 100)
}
function toString() {
return numbers.map(format)
}
n.counter = {
tick,
toString
}
}(namespace))
const counter = namespace.counter
counter.tick()
counter.tick()
console.log(counter.toString())
Examples
Example 1
This example shows that the local variables are not copied in the closure: the closure maintains a reference to the original variables themselves. It is as though the stack-frame stays alive in memory even after the outer function exits.
function foo() {
let x = 42
let inner = () => console.log(x)
x = x + 1
return inner
}
foo()() // logs 43
Example 2
In the following code, three methods log, increment, and update all close over the same lexical environment.
And every time createObject is called, a new execution context (stack frame) is created and a completely new variable x, and a new set of functions (log etc.) are created, that close over this new variable.
function createObject() {
let x = 42;
return {
log() { console.log(x) },
increment() { x++ },
update(value) { x = value }
}
}
const o = createObject()
o.increment()
o.log() // 43
o.update(5)
o.log() // 5
const p = createObject()
p.log() // 42
Example 3
If you are using variables declared using var, be careful you understand which variable you are closing over. Variables declared using var are hoisted. This is much less of a problem in modern JavaScript due to the introduction of let and const.
In the following code, each time around the loop, a new function inner is created, which closes over i. But because var i is hoisted outside the loop, all of these inner functions close over the same variable, meaning that the final value of i (3) is printed, three times.
function foo() {
var result = []
for (var i = 0; i < 3; i++) {
result.push(function inner() { console.log(i) } )
}
return result
}
const result = foo()
// The following will print `3`, three times...
for (var i = 0; i < 3; i++) {
result[i]()
}
Final points:
Whenever a function is declared in JavaScript closure is created.
Returning a function from inside another function is the classic example of closure, because the state inside the outer function is implicitly available to the returned inner function, even after the outer function has completed execution.
Whenever you use eval() inside a function, a closure is used. The text you eval can reference local variables of the function, and in the non-strict mode, you can even create new local variables by using eval('var foo = …').
When you use new Function(…) (the Function constructor) inside a function, it does not close over its lexical environment: it closes over the global context instead. The new function cannot reference the local variables of the outer function.
A closure in JavaScript is like keeping a reference (NOT a copy) to the scope at the point of function declaration, which in turn keeps a reference to its outer scope, and so on, all the way to the global object at the top of the scope chain.
A closure is created when a function is declared; this closure is used to configure the execution context when the function is invoked.
A new set of local variables is created every time a function is called.
Links
Douglas Crockford's simulated private attributes and private methods for an object, using closures.
A great explanation of how closures can cause memory leaks in IE if you are not careful.
MDN documentation on JavaScript Closures.
Every function in JavaScript maintains a link to its outer lexical environment. A lexical environment is a map of all the names (eg. variables, parameters) within a scope, with their values.
So, whenever you see the function keyword, code inside that function has access to variables declared outside the function.
function foo(x) {
var tmp = 3;
function bar(y) {
console.log(x + y + (++tmp)); // will log 16
}
bar(10);
}
foo(2);
This will log 16 because function bar closes over the parameter x and the variable tmp, both of which exist in the lexical environment of outer function foo.
Function bar, together with its link with the lexical environment of function foo is a closure.
A function doesn't have to return in order to create a closure. Simply by virtue of its declaration, every function closes over its enclosing lexical environment, forming a closure.
function foo(x) {
var tmp = 3;
return function (y) {
console.log(x + y + (++tmp)); // will also log 16
}
}
var bar = foo(2);
bar(10); // 16
bar(10); // 17
The above function will also log 16, because the code inside bar can still refer to argument x and variable tmp, even though they are no longer directly in scope.
However, since tmp is still hanging around inside bar's closure, it is available to be incremented. It will be incremented each time you call bar.
The simplest example of a closure is this:
var a = 10;
function test() {
console.log(a); // will output 10
console.log(b); // will output 6
}
var b = 6;
test();
When a JavaScript function is invoked, a new execution context ec is created. Together with the function arguments and the target object, this execution context also receives a link to the lexical environment of the calling execution context, meaning the variables declared in the outer lexical environment (in the above example, both a and b) are available from ec.
Every function creates a closure because every function has a link to its outer lexical environment.
Note that variables themselves are visible from within a closure, not copies.
FOREWORD: this answer was written when the question was:
Like the old Albert said : "If you can't explain it to a six-year old, you really don't understand it yourself.”. Well I tried to explain JS closures to a 27 years old friend and completely failed.
Can anybody consider that I am 6 and strangely interested in that subject ?
I'm pretty sure I was one of the only people that attempted to take the initial question literally. Since then, the question has mutated several times, so my answer may now seem incredibly silly & out of place. Hopefully the general idea of the story remains fun for some.
I'm a big fan of analogy and metaphor when explaining difficult concepts, so let me try my hand with a story.
Once upon a time:
There was a princess...
function princess() {
She lived in a wonderful world full of adventures. She met her Prince Charming, rode around her world on a unicorn, battled dragons, encountered talking animals, and many other fantastical things.
var adventures = [];
function princeCharming() { /* ... */ }
var unicorn = { /* ... */ },
dragons = [ /* ... */ ],
squirrel = "Hello!";
/* ... */
But she would always have to return back to her dull world of chores and grown-ups.
return {
And she would often tell them of her latest amazing adventure as a princess.
story: function() {
return adventures[adventures.length - 1];
}
};
}
But all they would see is a little girl...
var littleGirl = princess();
...telling stories about magic and fantasy.
littleGirl.story();
And even though the grown-ups knew of real princesses, they would never believe in the unicorns or dragons because they could never see them. The grown-ups said that they only existed inside the little girl's imagination.
But we know the real truth; that the little girl with the princess inside...
...is really a princess with a little girl inside.
Taking the question seriously, we should find out what a typical 6-year-old is capable of cognitively, though admittedly, one who is interested in JavaScript is not so typical.
On Childhood Development: 5 to 7 Years it says:
Your child will be able to follow two-step directions. For example, if you say to your child, "Go to the kitchen and get me a trash bag" they will be able to remember that direction.
We can use this example to explain closures, as follows:
The kitchen is a closure that has a local variable, called trashBags. There is a function inside the kitchen called getTrashBag that gets one trash bag and returns it.
We can code this in JavaScript like this:
function makeKitchen() {
var trashBags = ['A', 'B', 'C']; // only 3 at first
return {
getTrashBag: function() {
return trashBags.pop();
}
};
}
var kitchen = makeKitchen();
console.log(kitchen.getTrashBag()); // returns trash bag C
console.log(kitchen.getTrashBag()); // returns trash bag B
console.log(kitchen.getTrashBag()); // returns trash bag A
Further points that explain why closures are interesting:
Each time makeKitchen() is called, a new closure is created with its own separate trashBags.
The trashBags variable is local to the inside of each kitchen and is not accessible outside, but the inner function on the getTrashBag property does have access to it.
Every function call creates a closure, but there would be no need to keep the closure around unless an inner function, which has access to the inside of the closure, can be called from outside the closure. Returning the object with the getTrashBag function does that here.
The Straw Man
I need to know how many times a button has been clicked and do something on every third click...
Fairly Obvious Solution
// Declare counter outside event handler's scope
var counter = 0;
var element = document.getElementById('button');
element.addEventListener("click", function() {
// Increment outside counter
counter++;
if (counter === 3) {
// Do something every third time
console.log("Third time's the charm!");
// Reset counter
counter = 0;
}
});
<button id="button">Click Me!</button>
Now this will work, but it does encroach into the outer scope by adding a variable, whose sole purpose is to keep track of the count. In some situations, this would be preferable as your outer application might need access to this information. But in this case, we are only changing every third click's behavior, so it is preferable to enclose this functionality inside the event handler.
Consider this option
var element = document.getElementById('button');
element.addEventListener("click", (function() {
// init the count to 0
var count = 0;
return function(e) { // <- This function becomes the click handler
count++; // and will retain access to the above `count`
if (count === 3) {
// Do something every third time
console.log("Third time's the charm!");
//Reset counter
count = 0;
}
};
})());
<button id="button">Click Me!</button>
Notice a few things here.
In the above example, I am using the closure behavior of JavaScript. This behavior allows any function to have access to the scope in which it was created, indefinitely. To practically apply this, I immediately invoke a function that returns another function, and because the function I'm returning has access to the internal count variable (because of the closure behavior explained above) this results in a private scope for usage by the resulting function... Not so simple? Let's dilute it down...
A simple one-line closure
// _______________________Immediately invoked______________________
// | |
// | Scope retained for use ___Returned as the____ |
// | only by returned function | value of func | |
// | | | | | |
// v v v v v v
var func = (function() { var a = 'val'; return function() { alert(a); }; })();
All variables outside the returned function are available to the returned function, but they are not directly available to the returned function object...
func(); // Alerts "val"
func.a; // Undefined
Get it? So in our primary example, the count variable is contained within the closure and always available to the event handler, so it retains its state from click to click.
Also, this private variable state is fully accessible, for both readings and assigning to its private scoped variables.
There you go; you're now fully encapsulating this behavior.
Full Blog Post (including jQuery considerations)
Closures are hard to explain because they are used to make some behaviour work that everybody intuitively expects to work anyway. I find the best way to explain them (and the way that I learned what they do) is to imagine the situation without them:
const makePlus = function(x) {
return function(y) { return x + y; };
}
const plus5 = makePlus(5);
console.log(plus5(3));
What would happen here if JavaScript didn't know closures? Just replace the call in the last line by its method body (which is basically what function calls do) and you get:
console.log(x + 3);
Now, where's the definition of x? We didn't define it in the current scope. The only solution is to let plus5 carry its scope (or rather, its parent's scope) around. This way, x is well-defined and it is bound to the value 5.
TLDR
A closure is a link between a function and its outer lexical (ie. as-written) environment, such that the identifiers (variables, parameters, function declarations etc) defined within that environment are visible from within the function, regardless of when or from where the function is invoked.
Details
In the terminology of the ECMAScript specification, a closure can be said to be implemented by the [[Environment]] reference of every function-object, which points to the lexical environment within which the function is defined.
When a function is invoked via the internal [[Call]] method, the [[Environment]] reference on the function-object is copied into the outer environment reference of the environment record of the newly-created execution context (stack frame).
In the following example, function f closes over the lexical environment of the global execution context:
function f() {}
In the following example, function h closes over the lexical environment of function g, which, in turn, closes over the lexical environment of the global execution context.
function g() {
function h() {}
}
If an inner function is returned by an outer, then the outer lexical environment will persist after the outer function has returned. This is because the outer lexical environment needs to be available if the inner function is eventually invoked.
In the following example, function j closes over the lexical environment of function i, meaning that variable x is visible from inside function j, long after function i has completed execution:
function i() {
var x = 'mochacchino'
return function j() {
console.log('Printing the value of x, from within function j: ', x)
}
}
const k = i()
setTimeout(k, 500) // invoke k (which is j) after 500ms
In a closure, the variables in the outer lexical environment themselves are available, not copies.
function l() {
var y = 'vanilla';
return {
setY: function(value) {
y = value;
},
logY: function(value) {
console.log('The value of y is: ', y);
}
}
}
const o = l()
o.logY() // The value of y is: vanilla
o.setY('chocolate')
o.logY() // The value of y is: chocolate
The chain of lexical environments, linked between execution contexts via outer environment references, forms a scope chain and defines the identifiers visible from any given function.
Please note that in an attempt to improve clarity and accuracy, this answer has been substantially changed from the original.
OK, 6-year-old closures fan. Do you want to hear the simplest example of closure?
Let's imagine the next situation: a driver is sitting in a car. That car is inside a plane. Plane is in the airport. The ability of driver to access things outside his car, but inside the plane, even if that plane leaves an airport, is a closure. That's it. When you turn 27, look at the more detailed explanation or at the example below.
Here is how I can convert my plane story into the code.
var plane = function(defaultAirport) {
var lastAirportLeft = defaultAirport;
var car = {
driver: {
startAccessPlaneInfo: function() {
setInterval(function() {
console.log("Last airport was " + lastAirportLeft);
}, 2000);
}
}
};
car.driver.startAccessPlaneInfo();
return {
leaveTheAirport: function(airPortName) {
lastAirportLeft = airPortName;
}
}
}("Boryspil International Airport");
plane.leaveTheAirport("John F. Kennedy");
This is an attempt to clear up several (possible) misunderstandings about closures that appear in some of the other answers.
A closure is not only created when you return an inner function. In fact, the enclosing function does not need to return at all in order for its closure to be created. You might instead assign your inner function to a variable in an outer scope, or pass it as an argument to another function where it could be called immediately or any time later. Therefore, the closure of the enclosing function is probably created as soon as the enclosing function is called since any inner function has access to that closure whenever the inner function is called, before or after the enclosing function returns.
A closure does not reference a copy of the old values of variables in its scope. The variables themselves are part of the closure, and so the value seen when accessing one of those variables is the latest value at the time it is accessed. This is why inner functions created inside of loops can be tricky, since each one has access to the same outer variables rather than grabbing a copy of the variables at the time the function is created or called.
The "variables" in a closure include any named functions declared within the function. They also include arguments of the function. A closure also has access to its containing closure's variables, all the way up to the global scope.
Closures use memory, but they don't cause memory leaks since JavaScript by itself cleans up its own circular structures that are not referenced. Internet Explorer memory leaks involving closures are created when it fails to disconnect DOM attribute values that reference closures, thus maintaining references to possibly circular structures.
I wrote a blog post a while back explaining closures. Here's what I said about closures in terms of why you'd want one.
Closures are a way to let a function
have persistent, private variables -
that is, variables that only one
function knows about, where it can
keep track of info from previous times
that it was run.
In that sense, they let a function act a bit like an object with private attributes.
Full post:
So what are these closure thingys?
The original question had a quote:
If you can't explain it to a six-year old, you really don't understand it yourself.
This is how I'd try to explain it to an actual six-year-old:
You know how grown-ups can own a house, and they call it home? When a mom has a child, the child doesn't really own anything, right? But its parents own a house, so whenever someone asks "Where's your home?", the child can answer "that house!", and point to the house of its parents.
A "Closure" is the ability of the child to always (even if abroad) be able to refer to its home, even though it's really the parent's who own the house.
Closures are simple:
The following simple example covers all the main points of JavaScript closures.*
Here is a factory that produces calculators that can add and multiply:
function make_calculator() {
var n = 0; // this calculator stores a single number n
return {
add: function(a) {
n += a;
return n;
},
multiply: function(a) {
n *= a;
return n;
}
};
}
first_calculator = make_calculator();
second_calculator = make_calculator();
first_calculator.add(3); // returns 3
second_calculator.add(400); // returns 400
first_calculator.multiply(11); // returns 33
second_calculator.multiply(10); // returns 4000
The key point: Each call to make_calculator creates a new local variable n, which continues to be usable by that calculator's add and multiply functions long after make_calculator returns.
If you are familiar with stack frames, these calculators seem strange: How can they keep accessing n after make_calculator returns? The answer is to imagine that JavaScript doesn't use "stack frames", but instead uses "heap frames", which can persist after the function call that made them returns.
Inner functions like add and multiply, which access variables declared in an outer function**, are called closures.
That is pretty much all there is to closures.
* For example, it covers all the points in the "Closures for Dummies" article given in another answer, except example 6, which simply shows that variables can be used before they are declared, a nice fact to know but completely unrelated to closures. It also covers all the points in the accepted answer, except for the points (1) that functions copy their arguments into local variables (the named function arguments), and (2) that copying numbers creates a new number, but copying an object reference gives you another reference to the same object. These are also good to know but again completely unrelated to closures. It is also very similar to the example in this answer but a bit shorter and less abstract. It does not cover the point of this answer or this comment, which is that JavaScript makes it difficult to plug the current value of a loop variable into your inner function: The "plugging in" step can only be done with a helper function that encloses your inner function and is invoked on each loop iteration. (Strictly speaking, the inner function accesses the helper function's copy of the variable, rather than having anything plugged in.) Again, very useful when creating closures, but not part of what a closure is or how it works. There is additional confusion due to closures working differently in functional languages like ML, where variables are bound to values rather than to storage space, providing a constant stream of people who understand closures in a way (namely the "plugging in" way) that is simply incorrect for JavaScript, where variables are always bound to storage space, and never to values.
** Any outer function, if several are nested, or even in the global context, as this answer points out clearly.
Can you explain closures to a 5-year-old?*
I still think Google's explanation works very well and is concise:
/*
* When a function is defined in another function and it
* has access to the outer function's context even after
* the outer function returns.
*
* An important concept to learn in JavaScript.
*/
function outerFunction(someNum) {
var someString = 'Hey!';
var content = document.getElementById('content');
function innerFunction() {
content.innerHTML = someNum + ': ' + someString;
content = null; // Internet Explorer memory leak for DOM reference
}
innerFunction();
}
outerFunction(1);​
*A C# question
I tend to learn better by GOOD/BAD comparisons. I like to see working code followed by non-working code that someone is likely to encounter. I put together a jsFiddle that does a comparison and tries to boil down the differences to the simplest explanations I could come up with.
Closures done right:
console.log('CLOSURES DONE RIGHT');
var arr = [];
function createClosure(n) {
return function () {
return 'n = ' + n;
}
}
for (var index = 0; index < 10; index++) {
arr[index] = createClosure(index);
}
for (var index of arr) {
console.log(arr[index]());
}
In the above code createClosure(n) is invoked in every iteration of the loop. Note that I named the variable n to highlight that it is a new variable created in a new function scope and is not the same variable as index which is bound to the outer scope.
This creates a new scope and n is bound to that scope; this means we have 10 separate scopes, one for each iteration.
createClosure(n) returns a function that returns the n within that scope.
Within each scope n is bound to whatever value it had when createClosure(n) was invoked so the nested function that gets returned will always return the value of n that it had when createClosure(n) was invoked.
Closures done wrong:
console.log('CLOSURES DONE WRONG');
function createClosureArray() {
var badArr = [];
for (var index = 0; index < 10; index++) {
badArr[index] = function () {
return 'n = ' + index;
};
}
return badArr;
}
var badArr = createClosureArray();
for (var index of badArr) {
console.log(badArr[index]());
}
In the above code the loop was moved within the createClosureArray() function and the function now just returns the completed array, which at first glance seems more intuitive.
What might not be obvious is that since createClosureArray() is only invoked once only one scope is created for this function instead of one for every iteration of the loop.
Within this function a variable named index is defined. The loop runs and adds functions to the array that return index. Note that index is defined within the createClosureArray function which only ever gets invoked one time.
Because there was only one scope within the createClosureArray() function, index is only bound to a value within that scope. In other words, each time the loop changes the value of index, it changes it for everything that references it within that scope.
All of the functions added to the array return the SAME index variable from the parent scope where it was defined instead of 10 different ones from 10 different scopes like the first example. The end result is that all 10 functions return the same variable from the same scope.
After the loop finished and index was done being modified the end value was 10, therefore every function added to the array returns the value of the single index variable which is now set to 10.
Result
CLOSURES DONE RIGHT
n = 0
n = 1
n = 2
n = 3
n = 4
n = 5
n = 6
n = 7
n = 8
n = 9
CLOSURES DONE WRONG
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
Wikipedia on closures:
In computer science, a closure is a function together with a referencing environment for the nonlocal names (free variables) of that function.
Technically, in JavaScript, every function is a closure. It always has an access to variables defined in the surrounding scope.
Since scope-defining construction in JavaScript is a function, not a code block like in many other languages, what we usually mean by closure in JavaScript is a function working with nonlocal variables defined in already executed surrounding function.
Closures are often used for creating functions with some hidden private data (but it's not always the case).
var db = (function() {
// Create a hidden object, which will hold the data
// it's inaccessible from the outside.
var data = {};
// Make a function, which will provide some access to the data.
return function(key, val) {
if (val === undefined) { return data[key] } // Get
else { return data[key] = val } // Set
}
// We are calling the anonymous surrounding function,
// returning the above inner function, which is a closure.
})();
db('x') // -> undefined
db('x', 1) // Set x to 1
db('x') // -> 1
// It's impossible to access the data object itself.
// We are able to get or set individual it.
ems
The example above is using an anonymous function, which was executed once. But it does not have to be. It can be named (e.g. mkdb) and executed later, generating a database function each time it is invoked. Every generated function will have its own hidden database object. Another usage example of closures is when we don't return a function, but an object containing multiple functions for different purposes, each of those function having access to the same data.
The children will never forget the secrets they have shared with their parents, even after their parents are
gone. This is what closures are for functions.
The secrets for JavaScript functions are the private variables
var parent = function() {
var name = "Mary"; // secret
}
Every time you call it, the local variable "name" is created and given the name "Mary". And every time the function exits the variable is lost and the name is forgotten.
As you may guess, because the variables are re-created every time the function is called, and nobody else will know them, there must be a secret place where they are stored. It could be called Chamber of Secrets or stack or local scope but it doesn't matter. We know they are there, somewhere, hidden in the memory.
But, in JavaScript, there is this very special thing that functions which are created inside other functions, can also know the local variables of their parents and keep them as long as they live.
var parent = function() {
var name = "Mary";
var child = function(childName) {
// I can also see that "name" is "Mary"
}
}
So, as long as we are in the parent -function, it can create one or more child functions which do share the secret variables from the secret place.
But the sad thing is, if the child is also a private variable of its parent function, it would also die when the parent ends, and the secrets would die with them.
So to live, the child has to leave before it's too late
var parent = function() {
var name = "Mary";
var child = function(childName) {
return "My name is " + childName +", child of " + name;
}
return child; // child leaves the parent ->
}
var child = parent(); // < - and here it is outside
And now, even though Mary is "no longer running", the memory of her is not lost and her child will always remember her name and other secrets they shared during their time together.
So, if you call the child "Alice", she will respond
child("Alice") => "My name is Alice, child of Mary"
That's all there is to tell.
I put together an interactive JavaScript tutorial to explain how closures work.
What's a Closure?
Here's one of the examples:
var create = function (x) {
var f = function () {
return x; // We can refer to x here!
};
return f;
};
// 'create' takes one argument, creates a function
var g = create(42);
// g is a function that takes no arguments now
var y = g();
// y is 42 here
I do not understand why the answers are so complex here.
Here is a closure:
var a = 42;
function b() { return a; }
Yes. You probably use that many times a day.
There is no reason to believe closures are a complex design hack to address specific problems. No, closures are just about using a variable that comes from a higher scope from the perspective of where the function was declared (not run).
Now what it allows you to do can be more spectacular, see other answers.
A closure is where an inner function has access to variables in its outer function. That's probably the simplest one-line explanation you can get for closures.
Example for the first point by dlaliberte:
A closure is not only created when you return an inner function. In fact, the enclosing function does not need to return at all. You might instead assign your inner function to a variable in an outer scope, or pass it as an argument to another function where it could be used immediately. Therefore, the closure of the enclosing function probably already exists at the time that enclosing function was called since any inner function has access to it as soon as it is called.
var i;
function foo(x) {
var tmp = 3;
i = function (y) {
console.log(x + y + (++tmp));
}
}
foo(2);
i(3);
I know there are plenty of solutions already, but I guess that this small and simple script can be useful to demonstrate the concept:
// makeSequencer will return a "sequencer" function
var makeSequencer = function() {
var _count = 0; // not accessible outside this function
var sequencer = function () {
return _count++;
}
return sequencer;
}
var fnext = makeSequencer();
var v0 = fnext(); // v0 = 0;
var v1 = fnext(); // v1 = 1;
var vz = fnext._count // vz = undefined
You're having a sleep over and you invite Dan.
You tell Dan to bring one XBox controller.
Dan invites Paul.
Dan asks Paul to bring one controller. How many controllers were brought to the party?
function sleepOver(howManyControllersToBring) {
var numberOfDansControllers = howManyControllersToBring;
return function danInvitedPaul(numberOfPaulsControllers) {
var totalControllers = numberOfDansControllers + numberOfPaulsControllers;
return totalControllers;
}
}
var howManyControllersToBring = 1;
var inviteDan = sleepOver(howManyControllersToBring);
// The only reason Paul was invited is because Dan was invited.
// So we set Paul's invitation = Dan's invitation.
var danInvitedPaul = inviteDan(howManyControllersToBring);
alert("There were " + danInvitedPaul + " controllers brought to the party.");
The author of Closures has explained closures pretty well, explaining the reason why we need them and also explaining LexicalEnvironment which is necessary to understanding closures.
Here is the summary:
What if a variable is accessed, but it isn’t local? Like here:
In this case, the interpreter finds the variable in the
outer LexicalEnvironment object.
The process consists of two steps:
First, when a function f is created, it is not created in an empty
space. There is a current LexicalEnvironment object. In the case
above, it’s window (a is undefined at the time of function
creation).
When a function is created, it gets a hidden property, named [[Scope]], which references the current LexicalEnvironment.
If a variable is read, but can not be found anywhere, an error is generated.
Nested functions
Functions can be nested one inside another, forming a chain of LexicalEnvironments which can also be called a scope chain.
So, function g has access to g, a and f.
Closures
A nested function may continue to live after the outer function has finished:
Marking up LexicalEnvironments:
As we see, this.say is a property in the user object, so it continues to live after User completed.
And if you remember, when this.say is created, it (as every function) gets an internal reference this.say.[[Scope]] to the current LexicalEnvironment. So, the LexicalEnvironment of the current User execution stays in memory. All variables of User also are its properties, so they are also carefully kept, not junked as usually.
The whole point is to ensure that if the inner function wants to access an outer variable in the future, it is able to do so.
To summarize:
The inner function keeps a reference to the outer
LexicalEnvironment.
The inner function may access variables from it
any time even if the outer function is finished.
The browser keeps the LexicalEnvironment and all its properties (variables) in memory until there is an inner function which references it.
This is called a closure.
JavaScript functions can access their:
Arguments
Locals (that is, their local variables and local functions)
Environment, which includes:
globals, including the DOM
anything in outer functions
If a function accesses its environment, then the function is a closure.
Note that outer functions are not required, though they do offer benefits I don't discuss here. By accessing data in its environment, a closure keeps that data alive. In the subcase of outer/inner functions, an outer function can create local data and eventually exit, and yet, if any inner function(s) survive after the outer function exits, then the inner function(s) keep the outer function's local data alive.
Example of a closure that uses the global environment:
Imagine that the Stack Overflow Vote-Up and Vote-Down button events are implemented as closures, voteUp_click and voteDown_click, that have access to external variables isVotedUp and isVotedDown, which are defined globally. (For simplicity's sake, I am referring to StackOverflow's Question Vote buttons, not the array of Answer Vote buttons.)
When the user clicks the VoteUp button, the voteUp_click function checks whether isVotedDown == true to determine whether to vote up or merely cancel a down vote. Function voteUp_click is a closure because it is accessing its environment.
var isVotedUp = false;
var isVotedDown = false;
function voteUp_click() {
if (isVotedUp)
return;
else if (isVotedDown)
SetDownVote(false);
else
SetUpVote(true);
}
function voteDown_click() {
if (isVotedDown)
return;
else if (isVotedUp)
SetUpVote(false);
else
SetDownVote(true);
}
function SetUpVote(status) {
isVotedUp = status;
// Do some CSS stuff to Vote-Up button
}
function SetDownVote(status) {
isVotedDown = status;
// Do some CSS stuff to Vote-Down button
}
All four of these functions are closures as they all access their environment.
As a father of a 6-year-old, currently teaching young children (and a relative novice to coding with no formal education so corrections will be required), I think the lesson would stick best through hands-on play. If the 6-year-old is ready to understand what a closure is, then they are old enough to have a go themselves. I'd suggest pasting the code into jsfiddle.net, explaining a bit, and leaving them alone to concoct a unique song. The explanatory text below is probably more appropriate for a 10 year old.
function sing(person) {
var firstPart = "There was " + person + " who swallowed ";
var fly = function() {
var creature = "a fly";
var result = "Perhaps she'll die";
alert(firstPart + creature + "\n" + result);
};
var spider = function() {
var creature = "a spider";
var result = "that wiggled and jiggled and tickled inside her";
alert(firstPart + creature + "\n" + result);
};
var bird = function() {
var creature = "a bird";
var result = "How absurd!";
alert(firstPart + creature + "\n" + result);
};
var cat = function() {
var creature = "a cat";
var result = "Imagine That!";
alert(firstPart + creature + "\n" + result);
};
fly();
spider();
bird();
cat();
}
var person="an old lady";
sing(person);
INSTRUCTIONS
DATA: Data is a collection of facts. It can be numbers, words, measurements, observations or even just descriptions of things. You can't touch it, smell it or taste it. You can write it down, speak it and hear it. You could use it to create touch smell and taste using a computer. It can be made useful by a computer using code.
CODE: All the writing above is called code. It is written in JavaScript.
JAVASCRIPT: JavaScript is a language. Like English or French or Chinese are languages. There are lots of languages that are understood by computers and other electronic processors. For JavaScript to be understood by a computer it needs an interpreter. Imagine if a teacher who only speaks Russian comes to teach your class at school. When the teacher says "все садятся", the class would not understand. But luckily you have a Russian pupil in your class who tells everyone this means "everybody sit down" - so you all do. The class is like a computer and the Russian pupil is the interpreter. For JavaScript the most common interpreter is called a browser.
BROWSER: When you connect to the Internet on a computer, tablet or phone to visit a website, you use a browser. Examples you may know are Internet Explorer, Chrome, Firefox and Safari. The browser can understand JavaScript and tell the computer what it needs to do. The JavaScript instructions are called functions.
FUNCTION: A function in JavaScript is like a factory. It might be a little factory with only one machine inside. Or it might contain many other little factories, each with many machines doing different jobs. In a real life clothes factory you might have reams of cloth and bobbins of thread going in and T-shirts and jeans coming out. Our JavaScript factory only processes data, it can't sew, drill a hole or melt metal. In our JavaScript factory data goes in and data comes out.
All this data stuff sounds a bit boring, but it is really very cool; we might have a function that tells a robot what to make for dinner. Let's say I invite you and your friend to my house. You like chicken legs best, I like sausages, your friend always wants what you want and my friend does not eat meat.
I haven't got time to go shopping, so the function needs to know what we have in the fridge to make decisions. Each ingredient has a different cooking time and we want everything to be served hot by the robot at the same time. We need to provide the function with the data about what we like, the function could 'talk' to the fridge, and the function could control the robot.
A function normally has a name, parentheses and braces. Like this:
function cookMeal() { /* STUFF INSIDE THE FUNCTION */ }
Note that /*...*/ and // stop code being read by the browser.
NAME: You can call a function just about whatever word you want. The example "cookMeal" is typical in joining two words together and giving the second one a capital letter at the beginning - but this is not necessary. It can't have a space in it, and it can't be a number on its own.
PARENTHESES: "Parentheses" or () are the letter box on the JavaScript function factory's door or a post box in the street for sending packets of information to the factory. Sometimes the postbox might be marked for example cookMeal(you, me, yourFriend, myFriend, fridge, dinnerTime), in which case you know what data you have to give it.
BRACES: "Braces" which look like this {} are the tinted windows of our factory. From inside the factory you can see out, but from the outside you can't see in.
THE LONG CODE EXAMPLE ABOVE
Our code begins with the word function, so we know that it is one! Then the name of the function sing - that's my own description of what the function is about. Then parentheses (). The parentheses are always there for a function. Sometimes they are empty, and sometimes they have something in. This one has a word in: (person). After this there is a brace like this { . This marks the start of the function sing(). It has a partner which marks the end of sing() like this }
function sing(person) { /* STUFF INSIDE THE FUNCTION */ }
So this function might have something to do with singing, and might need some data about a person. It has instructions inside to do something with that data.
Now, after the function sing(), near the end of the code is the line
var person="an old lady";
VARIABLE: The letters var stand for "variable". A variable is like an envelope. On the outside this envelope is marked "person". On the inside it contains a slip of paper with the information our function needs, some letters and spaces joined together like a piece of string (it's called a string) that make a phrase reading "an old lady". Our envelope could contain other kinds of things like numbers (called integers), instructions (called functions), lists (called arrays). Because this variable is written outside of all the braces {}, and because you can see out through the tinted windows when you are inside the braces, this variable can be seen from anywhere in the code. We call this a 'global variable'.
GLOBAL VARIABLE: person is a global variable, meaning that if you change its value from "an old lady" to "a young man", the person will keep being a young man until you decide to change it again and that any other function in the code can see that it's a young man. Press the F12 button or look at the Options settings to open the developer console of a browser and type "person" to see what this value is. Type person="a young man" to change it and then type "person" again to see that it has changed.
After this we have the line
sing(person);
This line is calling the function, as if it were calling a dog
"Come on sing, Come and get person!"
When the browser has loaded the JavaScript code an reached this line, it will start the function. I put the line at the end to make sure that the browser has all the information it needs to run it.
Functions define actions - the main function is about singing. It contains a variable called firstPart which applies to the singing about the person that applies to each of the verses of the song: "There was " + person + " who swallowed". If you type firstPart into the console, you won't get an answer because the variable is locked up in a function - the browser can't see inside the tinted windows of the braces.
CLOSURES: The closures are the smaller functions that are inside the big sing() function. The little factories inside the big factory. They each have their own braces which mean that the variables inside them can't be seen from the outside. That's why the names of the variables (creature and result) can be repeated in the closures but with different values. If you type these variable names in the console window, you won't get its value because it's hidden by two layers of tinted windows.
The closures all know what the sing() function's variable called firstPart is, because they can see out from their tinted windows.
After the closures come the lines
fly();
spider();
bird();
cat();
The sing() function will call each of these functions in the order they are given. Then the sing() function's work will be done.
Okay, talking with a 6-year old child, I would possibly use following associations.
Imagine - you are playing with your little brothers and sisters in the entire house, and you are moving around with your toys and brought some of them into your older brother's room. After a while your brother returned from the school and went to his room, and he locked inside it, so now you could not access toys left there anymore in a direct way. But you could knock the door and ask your brother for that toys. This is called toy's closure; your brother made it up for you, and he is now into outer scope.
Compare with a situation when a door was locked by draft and nobody inside (general function execution), and then some local fire occur and burn down the room (garbage collector:D), and then a new room was build and now you may leave another toys there (new function instance), but never get the same toys which were left in the first room instance.
For an advanced child I would put something like the following. It is not perfect, but it makes you feel about what it is:
function playingInBrothersRoom (withToys) {
// We closure toys which we played in the brother's room. When he come back and lock the door
// your brother is supposed to be into the outer [[scope]] object now. Thanks god you could communicate with him.
var closureToys = withToys || [],
returnToy, countIt, toy; // Just another closure helpers, for brother's inner use.
var brotherGivesToyBack = function (toy) {
// New request. There is not yet closureToys on brother's hand yet. Give him a time.
returnToy = null;
if (toy && closureToys.length > 0) { // If we ask for a specific toy, the brother is going to search for it.
for ( countIt = closureToys.length; countIt; countIt--) {
if (closureToys[countIt - 1] == toy) {
returnToy = 'Take your ' + closureToys.splice(countIt - 1, 1) + ', little boy!';
break;
}
}
returnToy = returnToy || 'Hey, I could not find any ' + toy + ' here. Look for it in another room.';
}
else if (closureToys.length > 0) { // Otherwise, just give back everything he has in the room.
returnToy = 'Behold! ' + closureToys.join(', ') + '.';
closureToys = [];
}
else {
returnToy = 'Hey, lil shrimp, I gave you everything!';
}
console.log(returnToy);
}
return brotherGivesToyBack;
}
// You are playing in the house, including the brother's room.
var toys = ['teddybear', 'car', 'jumpingrope'],
askBrotherForClosuredToy = playingInBrothersRoom(toys);
// The door is locked, and the brother came from the school. You could not cheat and take it out directly.
console.log(askBrotherForClosuredToy.closureToys); // Undefined
// But you could ask your brother politely, to give it back.
askBrotherForClosuredToy('teddybear'); // Hooray, here it is, teddybear
askBrotherForClosuredToy('ball'); // The brother would not be able to find it.
askBrotherForClosuredToy(); // The brother gives you all the rest
askBrotherForClosuredToy(); // Nothing left in there
As you can see, the toys left in the room are still accessible via the brother and no matter if the room is locked. Here is a jsbin to play around with it.
A function in JavaScript is not just a reference to a set of instructions (as in C language), but it also includes a hidden data structure which is composed of references to all nonlocal variables it uses (captured variables). Such two-piece functions are called closures. Every function in JavaScript can be considered a closure.
Closures are functions with a state. It is somewhat similar to "this" in the sense that "this" also provides state for a function but function and "this" are separate objects ("this" is just a fancy parameter, and the only way to bind it permanently to a function is to create a closure). While "this" and function always live separately, a function cannot be separated from its closure and the language provides no means to access captured variables.
Because all these external variables referenced by a lexically nested function are actually local variables in the chain of its lexically enclosing functions (global variables can be assumed to be local variables of some root function), and every single execution of a function creates new instances of its local variables, it follows that every execution of a function returning (or otherwise transferring it out, such as registering it as a callback) a nested function creates a new closure (with its own potentially unique set of referenced nonlocal variables which represent its execution context).
Also, it must be understood that local variables in JavaScript are created not on the stack frame, but on the heap and destroyed only when no one is referencing them. When a function returns, references to its local variables are decremented, but they can still be non-null if during the current execution they became part of a closure and are still referenced by its lexically nested functions (which can happen only if the references to these nested functions were returned or otherwise transferred to some external code).
An example:
function foo (initValue) {
//This variable is not destroyed when the foo function exits.
//It is 'captured' by the two nested functions returned below.
var value = initValue;
//Note that the two returned functions are created right now.
//If the foo function is called again, it will return
//new functions referencing a different 'value' variable.
return {
getValue: function () { return value; },
setValue: function (newValue) { value = newValue; }
}
}
function bar () {
//foo sets its local variable 'value' to 5 and returns an object with
//two functions still referencing that local variable
var obj = foo(5);
//Extracting functions just to show that no 'this' is involved here
var getValue = obj.getValue;
var setValue = obj.setValue;
alert(getValue()); //Displays 5
setValue(10);
alert(getValue()); //Displays 10
//At this point getValue and setValue functions are destroyed
//(in reality they are destroyed at the next iteration of the garbage collector).
//The local variable 'value' in the foo is no longer referenced by
//anything and is destroyed too.
}
bar();
An answer for a six-year-old (assuming he knows what a function is and what a variable is, and what data is):
Functions can return data. One kind of data you can return from a function is another function. When that new function gets returned, all the variables and arguments used in the function that created it don't go away. Instead, that parent function "closes." In other words, nothing can look inside of it and see the variables it used except for the function it returned. That new function has a special ability to look back inside the function that created it and see the data inside of it.
function the_closure() {
var x = 4;
return function () {
return x; // Here, we look back inside the_closure for the value of x
}
}
var myFn = the_closure();
myFn(); //=> 4
Another really simple way to explain it is in terms of scope:
Any time you create a smaller scope inside of a larger scope, the smaller scope will always be able to see what is in the larger scope.
Perhaps a little beyond all but the most precocious of six-year-olds, but a few examples that helped make the concept of closure in JavaScript click for me.
A closure is a function that has access to another function's scope (its variables and functions). The easiest way to create a closure is with a function within a function; the reason being that in JavaScript a function always has access to its containing function’s scope.
function outerFunction() {
var outerVar = "monkey";
function innerFunction() {
alert(outerVar);
}
innerFunction();
}
outerFunction();
ALERT: monkey
In the above example, outerFunction is called which in turn calls innerFunction. Note how outerVar is available to innerFunction, evidenced by its correctly alerting the value of outerVar.
Now consider the following:
function outerFunction() {
var outerVar = "monkey";
function innerFunction() {
return outerVar;
}
return innerFunction;
}
var referenceToInnerFunction = outerFunction();
alert(referenceToInnerFunction());
ALERT: monkey
referenceToInnerFunction is set to outerFunction(), which simply returns a reference to innerFunction. When referenceToInnerFunction is called, it returns outerVar. Again, as above, this demonstrates that innerFunction has access to outerVar, a variable of outerFunction. Furthermore, it is interesting to note that it retains this access even after outerFunction has finished executing.
And here is where things get really interesting. If we were to get rid of outerFunction, say set it to null, you might think that referenceToInnerFunction would loose its access to the value of outerVar. But this is not the case.
function outerFunction() {
var outerVar = "monkey";
function innerFunction() {
return outerVar;
}
return innerFunction;
}
var referenceToInnerFunction = outerFunction();
alert(referenceToInnerFunction());
outerFunction = null;
alert(referenceToInnerFunction());
ALERT: monkey
ALERT: monkey
But how is this so? How can referenceToInnerFunction still know the value of outerVar now that outerFunction has been set to null?
The reason that referenceToInnerFunction can still access the value of outerVar is because when the closure was first created by placing innerFunction inside of outerFunction, innerFunction added a reference to outerFunction’s scope (its variables and functions) to its scope chain. What this means is that innerFunction has a pointer or reference to all of outerFunction’s variables, including outerVar. So even when outerFunction has finished executing, or even if it is deleted or set to null, the variables in its scope, like outerVar, stick around in memory because of the outstanding reference to them on the part of the innerFunction that has been returned to referenceToInnerFunction. To truly release outerVar and the rest of outerFunction’s variables from memory you would have to get rid of this outstanding reference to them, say by setting referenceToInnerFunction to null as well.
//////////
Two other things about closures to note. First, the closure will always have access to the last values of its containing function.
function outerFunction() {
var outerVar = "monkey";
function innerFunction() {
alert(outerVar);
}
outerVar = "gorilla";
innerFunction();
}
outerFunction();
ALERT: gorilla
Second, when a closure is created, it retains a reference to all of its enclosing function’s variables and functions; it doesn’t get to pick and choose. And but so, closures should be used sparingly, or at least carefully, as they can be memory intensive; a lot of variables can be kept in memory long after a containing function has finished executing.
I'd simply point them to the Mozilla Closures page. It's the best, most concise and simple explanation of closure basics and practical usage that I've found. It is highly recommended to anyone learning JavaScript.
And yes, I'd even recommend it to a 6-year old -- if the 6-year old is learning about closures, then it's logical they're ready to comprehend the concise and simple explanation provided in the article.

Supporting "recursive objects" in lua

I'm fairly new to lua and have the following problem with an assignment from a class:
We currently extend lua to support objects and inheritance. The Syntax for that is
Class{'MyClass',
attribute1 = String,
attribute2 = Number
}
Class{'MySubClass', MyClass,
attribute3 = Number
}
This works perfectly fine. The real problem lies within the next task: We should support "recursive types", that means a call like
Class{'MyClass', attribute = MyClass}
should result in an class with a field of the same type as the class. When this "class-constructor" is called the variable MyClass is nil, thats why the parameter table doesnt't have an entry attribute. How is it possible to access this attribute?
My first thought was using some kind of nil-table which gets returned every time the global __index is called with an unset key. This nil-table should behave like the normal nil, but can be checked for in the "class-constructor". The problem with this approach are comparisons like nil == unknown. This should return true, but as the __eq meta method of the nil-table is never called we cannot return true.
Is there another approach I'm currently just ignoring? Any hint is greatly appreciated.
Thanks in advance.
Edit:
Here the relevant part of the "testfile". The test by which the code is rated in class is another one and gets published later.
three = 3
print( three == 3 , "Should be true")
print( unknown == nil , "Should be true" )
Class{'AClass', name = String, ref = AClass}
function AClass:write()
print("AClass:write(), name of AClass:", self.name)
end
aclass = AClass:create("A. Class")
aclass:write()
Since MyClass is just a lookup in the global table (_G), you could mess with its metatable's __index to return a newly-defined MyClass object (which you would later need to fill with the details).
However, while feasible, such an implementation is
wildly unsafe, as you could end up with an undefined class (or worse, you may end up inadvertantly creating an infinite lookup loop. Trust me, I've been there)
very hard to debug, as every _G lookup for a non-existing variable will now return a newly created class object instead of nil (this problem could somewhat be reduced by requiring that class names start with an uppercase character)
If you go that route, be sure to also override __newindex.
How about providing the argument in string form?
Class{'MyClass', attribute = 'MyClass'}
Detect strings inside the implementation of Class and process them with _G[string] after creating the class
Or alternatively, use a function to delay the lookup:
Class{'MyClass', attribute = function() return MyClass end}

Corona LUA and OOP Design

So I come from the traditional game development that uses OOP principles and from what I've seen you can mimic this using LUA once you know what you are doing. In some of the code postings I found out how you can use the director class and create files that have a new() function etc.
What I'm looking for is a way to manage my weapons. I have a player and an opponent and I would prefer to have one weapon class, say weaponCanon. What I have done is:
-- private vars here
local power
local canonSprite
local whatever
local someFunction = function()
...
end
-- Private stuff here
local weaponCanon = {}
weaponCanon.fire = function(atX, atY)
...
end
weaponCanon.reset = function()
...
end
return weaponCanon
Then in my level code I simply do:
local weaponCanon = require("weaponCanon")
weaponCanon.fire(100, 100)
This works great and allows me to use a "private" and "public" mentality when coding up my weapons. The problem is that if I want the player and opponent to have a canon:
local playerWeapon = require("weaponCanon")
local opponentWeapon = require("weaponCanon")
This simply returns the same object instead of a new instance to that object. So I only get one weaponCanon at the opponentWeapon location. This is obviously now what I want/need.
Our game has many weapons in it and it would be nice to only have one version of each file with a setting telling us if its the opponents weapon or players weapon. The alternative is to copy each file and create a weaponPlayerCanon and a weaponOpponentCanon but I cringe at the thought of modifications to one file and having to change 2+ files every time.
How can I make it return an instance and what is the structure of the LUA file to do so?
Thanks or any and all help
-d
If later on you start needing inheritance (i.e. LaserCannon is a subclass of Weapon) you will probably need to use metatables more profoundly.
There are lots of libraries that will allow you to do "oop on top of Lua". You can see a very good list here:
http://lua-users.org/wiki/ObjectOrientedProgramming
I'm the author of middleclass. With my lib, you would have to do something like this:
local Weapon = class('Weapon')
function Weapon:initialize(a,b,c)
self.x,self.y,self.z = a,b,c
end
function Weapon:fire(x,y)
...
end
LaserCannon would be easy to implement - you just pass a second parameter to class:
local LaserCannon = class('LaserCannon', Weapon)
function LaserCannon:initialize(a,b,c,d)
self.w = d
Weapon.initialize(self, a,b,c) -- superclass' constructor
end
function LaserCannon:foo()
...
end
You could use it like this:
require 'middleclass' -- so you can use "class"
LaserCannon = require 'laser_cannon'
local playerWeapon = LaserCannon:new() -- a laser
local opponentWeapon = Weapon:new() -- a regular generic weapon
opponentWeapon:fire(100,200) -- typical use
playerWeapon:fire(100, 200) -- LaserCannon inherits fire from Weapon
playerWeapon:foo() -- LaserCannon-exclusive
This is with middleclass, which is the one I prefer, since I made it. Other libraries on the page I mentioned before offer similar features.
I guess you are trying to model a class with your source file. This means you should also have a function to create a new instance of that class unless you want them to share all their state.
Something along the lines of (untested):
local WeaponCannon = {}
WeaponCannon.__index = WeaponCannon
function WeaponCannon:new()
return setmetatable({}, self)
end
function WeaponCannon:fire(x, y)
-- Do something via the self reference and arguments (x, y)
end
return WeaponCannon
And in your calling code (also untested):
require('WeaponCannon')
local playerWeapon = WeaponCannon:new()
local opponentWeapon = WeaponCannon:new()
Although you create a new table for the weapon object, you don't create new variables. Any variables declared at the top of your module like that are essentially static variables (ie. variables shared by all instances of a class.) To create variables that are unique to that object you need to create them in the table, something like:
weaponCannon = {}
weaponCannon.power = 10
And anyway you only create an object once, you need a "constructor" function that creates the tables:
function new()
local weaponCannon = {}
weaponCannon.power = 10
end
Incidentally, two other things that aren't directly related to your answer but can be very useful modifications to your code. First off, using a colon instead of a period to call functions in a method will allow you to use the "self" keyword inside the method, something like:
function weaponCannon:fire()
--this is only a test
print(self.power)
end
then
local playerWeapon = require("weaponCanon")
playerWeapon:fire()
Second, you can actually use display objects as tables, rather than having to create an empty table and then sticking the display object into that empty table:
weaponCannon = display.newImage("cannon.png")
weaponCannon.power = 10
Note that you can't set the meta-table if you do this however. I find this approach looks more logical and prefer not to use meta-tables myself, but that's your call.
There are no objects here- you just have a bunch of global data. You really need to be making instances.
function NewWeapon(arg)
return {
fire = function(self, atX, atY)
print(self.var)
end,
var = arg,
}
end
NewWeapon(3):fire(1, 2)
NewWeapon(7):fire(3, 5)
I like ponzao's answer. Would however change it to:
local WeaponCannon = {}
function WeaponCannon:new()
local instance = {}
setmetatable(instance, {__index = WeaponCannon})
-- setup your new instance here
return instance
end
function WeaponCannon:fire(x, y)
-- Do something via the self reference and arguments (x, y)
end
return WeaponCannon
And in your calling code:
local WeaponCanon = require('WeaponCannon')
local playerWeapon = WeaponCannon:new()
local opponentWeapon = WeaponCannon:new()
What I've changed:
Created a local instance variable to allow for setup before returning it
More compact way of setting the metatable
Use a variable for the class when calling the code

Assignment of objects in VB6

I am attempting to create two identical objects in VB6 by assignment statements; something like this...
Dim myobj1 As Class1
Dim myobj2 As Class1
Set myobj1 = New Class1
myobj1.myval = 1
Set myobj2 = myobj1
It has become apparent that this doesn't create two objects but rather two references to the same object, which isn't what I am after. Is there any way to create a second object in this sort of way, or do I have to copy the object one member at a time...
Set myobj2 = new Class1
myobj2.mem1 = myobj1.mem1
...
?
Edit 2 Scott Whitlock has updated his excellent answer and I have incorporated his changes into this now-working code snippet.
Private Type MyMemento
Value1 As Integer
Value2 As String
End Type
Private Memento As MyMemento
Public Property Let myval(ByVal newval As Integer)
Memento.Value1 = newval
End Property
Public Property Get myval() As Integer
myval = Memento.Value1
End Property
Friend Property Let SetMemento(new_memento As MyMemento)
Memento = new_memento
End Property
Public Function Copy() As Class1
Dim Result As Class1
Set Result = New Class1
Result.SetMemento = Memento
Set Copy = Result
End Function
One then performs the assignment in the code thus...
Set mysecondobj = myfirstobj.Copy
Like many modern languages, VB6 has value types and reference types. Classes define reference types. On the other hand, your basic types like Integer are value types.
The basic difference is in assignment:
Dim a as Integer
Dim b as Integer
a = 2
b = a
a = 1
The result is that a is 1 and b is 2. That's because assignment in value types makes a copy. That's because each variable has space allocated for the value on the stack (in the case of VB6, an Integer takes up 2 bytes on the stack).
For classes, it works differently:
Dim a as MyClass
Dim b as MyClass
Set a = New MyClass
a.Value1 = 2
Set b = a
a.Value1 = 1
The result is that both a.Value1 and b.Value1 are 1. That's because the state of the object is stored in the heap, not on the stack. Only the reference to the object is stored on the stack, so Set b = a overwrites the reference. Interestingly, VB6 is explicit about this by forcing you to use the Set keyword. Most other modern languages don't require this.
Now, you can create your own value types (in VB6 they're called User Defined Types, but in most other languages they're called structs or structures). Here's a tutorial.
The differences between a class and a user defined type (aside from a class being a reference type and a UDT being a value type) is that a class can contain behaviors (methods and properties) where a UDT cannot. If you're just looking for a record-type class, then a UDT may be your solution.
You can use a mix of these techniques. Let's say you need a Class because you have certain behaviors and calculations that you want to include along with the data. You can use the memento pattern to hold the state of an object inside of a UDT:
Type MyMemento
Value1 As Integer
Value2 As String
End Type
In your class, make sure that all your internal state is stored inside a private member of type MyMemento. Write your properties and methods so they only use data in that one private member variable.
Now making a copy of your object is simple. Just write a new method on your class called Copy() that returns a new instance of your class and initialize it with a copy of its own memento:
Private Memento As MyMemento
Friend Sub SetMemento(NewMemento As MyMemento)
Memento = NewMemento
End Sub
Public Function Copy() as MyClass
Dim Result as MyClass
Set Result = new MyClass
Call Result.SetMemento(Memento)
Set Copy = Result
End Function
The Friend only hides it from stuff outside your project, so it doesn't do much to hide the SetMemento sub, but it's all you can do with VB6.
HTH
#Scott Whitlock, I was not able to make your code work but if it works it would be great.
I've created a regular module where I put the memento type
Type MyMemento
Value1 As Integer
Value2 As String
End Type
Then I create a class module called MyClass with the code
Private Memento As MyMemento
Friend Sub SetMemento(NewMemento As MyMemento)
Memento = NewMemento
End Sub
Public Function Copy() as MyClass
Dim Result as MyClass
Set Result = new MyClass
Result.SetMemento(Memento)
Set Copy = Result
End Function
Finally I try to call the copy function in another regular module like this
Sub Pruebas()
Dim Primero As MyClass, segundo As MyClass
Set Primero = New MyClass
Set segundo = New MyClass
Set segundo = Primero.Copy
End Sub
I get the message (below the picture): Error de compilacion: El tipo de agumento de ByRef no coincide
Here is an image (short of 10 points so here is the link): http://i.stack.imgur.com/KPdBR.gif
I was not able to get the message in English, I live in Spain.
Would you be so kind to provide with an example in VBA Excel?, I have been really trying to make this work.
Thanks for your work
===============================================
EDIT: Problem Solved:
The problem was on line "Result.SetMemento(Memento)", in VBA it needed to be called with "Call"
Public Function Copy() As MyClass
Dim Result As MyClass
Set Result = New MyClass
Call Result.SetMemento(Memento)
Set Copy = Result
End Function
It works great, thanks Scott Whitlock, you are a genius
or do I have to copy the object one member at a time...
Unfortunately yes.
It is possible (but technically very very difficult) to write a COM server in C++ that - using the IDispatch interface - will copy the value of each property, but really this is High Temple programming, if I had to do it, I don't I know if I could do it, but I'd be looking at something like 10 days work ( and I know how COM is implemented in C++, I'd also need to investigate to see if ATL framework has anything to help etc).
I worked with Vb3, 4,5 & 6 for something like 10 years (hands on, 5 days a week) and never found a good way to do this, beyond manually implementing serialisation patterns like Mementos and Save & Store, which really just boiled down to fancy ways of copying each member, one at a time.

How have you dealt with the lack of constructors in VB6?

VB6 classes have no parameterized constructors. What solution have you chosen for this? Using factory methods seems like the obvious choice, but surprise me!
I usually stick to factory methods, where I put the "constructors" for related classes in the same module (.BAS extension). Sadly, this is far from optimal since you can't really limit access to the normal object creation in VB6 - you just have to make a point of only creating your objects through the factory.
What makes it worse is having to jump between the actual object and your factory method, since organization in the IDE itself is cumbersome at best.
How about using the available class initializer? This behaves like a parameterless constructor:
Private Sub Class_Initialize()
' do initialization here
End Sub
I use a mix of factory functions (in parent classes) that then create an instance of the object and call a Friend Init() method.
Class CObjects:
Public Function Add(ByVal Param1 As String, ByVal Param2 As Long) As CObject
Dim Obj As CObject
Set Obj = New CObject
Obj.Init Param1, Param2
Set Add = Obj
End Function
Class CObject:
Friend Sub Init(ByVal Param1 As String, ByVal Param2 As Long)
If Param1 = "" Then Err.Raise 123, , "Param1 not set"
If Param2 < 0 Or Param2 > 15 Then Err.Raise 124, , "Param2 out of range"
'Init object state here
End Sub
I know the Friend scope won't have any effect in the project, but it acts as a warning that this is for internal use only.
If these objects are exposed via COM then the Init method can't be called, and setting the class to PublicNotCreatable stops it being created.
This solution is far from perfect, however, this is what I ended up doing for some of my legacy projects. It's somewhat memory-efficient for storage, but just looking up something definitely takes more time than otherwise required, especially for the huge structs.
Suppose you need to implement the following,
type user
id as long
name as String
desc as String
end type
But notice that VB6 natively supports Strings. So Instead of using structs, have "fake-struct" functions such as
Public Function user_raw(ByVal id as Long, ByRef name as String, ByRef desc as String) as String
Const RAW_DELIM as String = "|"
user_raw = cstr(id) & RAW_DELIM & name & RAW_DELIM & desc
End Function
So as a result, you will have passable-by-value (hence stackable into arrays, or multiline Strings), "fake-structs" made of strings such as
1|Foo|The boss of VB
2|Bar|Foo's apprentice
So the construct also counts as a crude way to perform to_string(). On the slightly good side, such storage is almost instantly convertible to the Markdown table syntax.
Later on, you can retrieve data from the struct by doing something like,
Public const RAW_DELIM as String = "|"
Public Const POS_USER_ID = 0
Public Const POS_USER_NAME = 1
Public Const POS_USER_DESC = 2
'...
public function get_raw_variable(byref user as String, byval var as integer) as String
dim buf() as String
buf = SPLIT(user, "|")
Assert ubound(buf) <= var
get_raw_variable = buf(var)
end function
The retrieval is sure inefficient, but is about the best you can have. Good luck