Last active
December 14, 2015 11:29
-
-
Save graue/5079734 to your computer and use it in GitHub Desktop.
Weirdness with JS closures (Lua behaves differently).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NOTE: Scroll down for explanation (the difference turns out to be scoping, not closures per se). | |
$ cat juices.lua | |
local fruits = {"apple", "orange", "grape"} | |
local juicers = {} | |
for i,v in ipairs(fruits) do | |
local fruit = v | |
juicers[i] = function() return fruit .. " juice" end | |
end | |
print(juicers[1]()); | |
print(juicers[2]()); | |
print(juicers[3]()); | |
$ lua juices.lua | |
apple juice | |
orange juice | |
grape juice | |
$ cat juices.js | |
var fruits = ["apple", "orange", "grape"]; | |
var juicers = []; | |
for (var i in fruits) { | |
var fruit = fruits[i]; | |
juicers[i] = function() { return fruit + " juice"; } | |
} | |
console.log(juicers[0]()); | |
console.log(juicers[1]()); | |
console.log(juicers[2]()); | |
$ node juices.js | |
grape juice | |
grape juice | |
grape juice |
yeah, so long story short, block scoping makes the world sane and python and javascript are inferior for not having it. that's my conclusion to all this :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So closures actually work the same way in Lua as in JavaScript and Python. If you write the loop like this in Lua:
...you again get "grape juice" three times. None of the 3 languages are copying variables when they create a closure. In all three languages, the closure references the original variable, which can change.
But in Lua, a new variable called
v
is created in each iteration of the loop; it doesn't update the oldv
. Likewise in the code up top, a new local variable calledfruit
was created on each iteration of the loop. In this version here we had to explicitly override that behavior. Closures are the same between Lua and JS/Python; scoping is not.