javascript - Why let and var bindings behave differently using setTimeout function? -
this question has answer here:
this code logs 6
, 6 times:
(function timer() { (var i=0; i<=5; i++) { settimeout(function clog() {console.log(i)}, i*1000); } })();
but code...
(function timer() { (let i=0; i<=5; i++) { settimeout(function clog() {console.log(i)}, i*1000); } })();
... logs following result:
0 1 2 3 4 5
why?
is because let
binds inner scope each item differently , var
keeps latest value of i
?
with var
have function scope, , 1 shared binding of loop iterations - i.e. i
in every settimeout callback means the same variable finally equal 6 after loop iteration ends.
with let
have block scope , when used in for
loop new binding each iteration - i.e. i
in every settimeout callback means a different variable, each of has different value: first 1 0, next 1 one etc.
so this:
(function timer() { (let = 0; <= 5; i++) { settimeout(function clog() { console.log(i); }, * 1000); } })();
is equivalent using var:
(function timer() { (var j = 0; j <= 5; j++) { (function () { var = j; settimeout(function clog() { console.log(i); }, * 1000); }()); } })();
using invoked function expression use function scope in similar way block scope works in example let
.
it written shorter without using j
name, perhaps not clear:
(function timer() { (var = 0; <= 5; i++) { (function (i) { settimeout(function clog() { console.log(i); }, * 1000); }(i)); } })();
and shorter arrow functions:
(() => { (var = 0; <= 5; i++) { (i => settimeout(() => console.log(i), * 1000))(i); } })();
(but if can use arrow functions, there's no reason use var
.)
this how babel.js translates example let
run in environments let
not available:
"use strict"; (function timer() { var _loop = function (i) { settimeout(function clog() { console.log(i); }, * 1000); }; (var = 0; <= 5; i++) { _loop(i); } })();
thanks michael geary posting link babel.js in comments. see link in comment live demo can change in code , watch translation taking place immediately. it's interesting see how other es6 features translated well.
Comments
Post a Comment