Last active
October 3, 2016 05:07
-
-
Save turboza/207c4806595db79952af62eda2005d14 to your computer and use it in GitHub Desktop.
Closure gotcha
This file contains 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
/* | |
* This code snippet give an unexpected result because the closure (function inside function) | |
* that will preserve the local variable "i" eventhough buildAction is finished | |
* So every action in array will refer to the same "i" which is 4 after finishing loop. | |
* | |
* Result :( | |
* ``` | |
* "item 4 = undefined" | |
* "item 4 = undefined" | |
* "item 4 = undefined" | |
* "item 4 = undefined" | |
* ``` | |
*/ | |
function buildActions(list) { | |
var actions = []; | |
for (var i=0; i<list.length; i++) { | |
actions.push(() => { | |
console.log(`item ${i} = ${list[i]}`) | |
}); | |
} | |
return actions; | |
} | |
var list = [9, 10, 11, 12]; | |
var actions = buildActions(list); | |
actions.forEach(action => action()); |
This file contains 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
/* | |
* This code snippet is a fix from closure-issue.js with 1 thing change from var i --> let i (ES2015) | |
* Because let/const will only exist in the { } scope, let i will create new i for every iteration. | |
* | |
* Result :) | |
* ``` | |
* "item 0 = 9" | |
* "item 1 = 10" | |
* "item 2 = 11" | |
* "item 3 = 12" | |
* ``` | |
*/ | |
function buildActions(list) { | |
var actions = []; | |
for (let i=0; i<list.length; i++) { // <--- Just change var to let here | |
actions.push(() => { | |
console.log(`item ${i} = ${list[i]}`) | |
}); | |
} | |
return actions; | |
} | |
var list = [9, 10, 11, 12]; | |
var actions = buildActions(list); | |
actions.forEach(action => action()); |
This file contains 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
/* | |
* Look more closely on transpiled version with babel for how it's fixed in ES5 | |
* ref: https://babeljs.io/repl (You can paste the ES2015+ code to see how it is transpiled) | |
*/ | |
"use strict"; | |
function buildActions(list) { | |
var actions = []; | |
var _loop = function _loop(i) { | |
actions.push(function () { | |
console.log("item " + i + " = " + list[i]); | |
}); | |
}; | |
for (var i = 0; i < list.length; i++) { | |
_loop(i); | |
} | |
return actions; | |
} | |
var list = [9, 10, 11, 12]; | |
var actions = buildActions(list); | |
actions.forEach(function (action) { | |
return action(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment