javascript - Why let and var bindings behave differently using setTimeout function? -


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

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -