Last active
February 10, 2023 09:42
-
-
Save aneurysmjs/88f8ec8054c91d918418e3e55faefcd8 to your computer and use it in GitHub Desktop.
practical use of 'var' statement
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
/* | |
* @desc closure in loops | |
*/ | |
// the problem here, is we're thinking we're getting | |
// a new 'i' for each iteration, so at the end it only | |
// prints 6, because 'i' is 6 at the end of the loop and | |
// the timers runs after so it'll print 6. | |
for (var i = 0; i <= 5; i += 1) { | |
setTimeout(function () { | |
console.log('i: ' + i); | |
}, 1000); | |
} // => i: 5 | |
// the problem is, "why we don't get a new 'i' for each iteration?" | |
// and that's because we use the 'var' statement, we made one 'i' | |
// attached to the existing scope and offcourse all of the five inner | |
// functions they are gonna close over the exact same 'i' and reveal | |
// the exact same answer for 'i'. | |
// see at: http://exploringjs.com/es6/ch_variables.html#sec_let-const-loop-heads | |
// `var-declaring a variable in the head of a for loop creates a single binding (storage space) for that variable` | |
// so to get a new variable for each iteration, we can use the following: | |
// 1) IIFE | |
// so we're legitimately creating a new 'i', so the 'i' we're closing on | |
// line 27 is same on line 25 and not the one of the head of the for-loop | |
for (var i = 0; i <= 5; i += 1) { | |
(function (i) { | |
setTimeout(function () { | |
console.log('i: ' + i); | |
}, 1000); | |
}(i)); | |
} // => i: 0...5 | |
// 2) Block scope | |
for (var i = 0; i <= 5; i += 1) { | |
let j = i; | |
setTimeout(function () { | |
console.log('j: ' + j); | |
}, 1000); | |
} // => i: 0...5 | |
// 3) use 'let; for the head of the loop | |
for (let i = 0; i <= 5; i += 1) { | |
setTimeout(function () { | |
console.log('i: ' + i); | |
}, 1000); | |
} // => i: 0...5 | |
/* | |
* @desc nested scope | |
*/ | |
function nested() { | |
var foo = 0; | |
setTimeout(function () { | |
var bar = 1; | |
console.log('bar', bar += 1); | |
setTimeout(function () { | |
console.log('foo + bar', foo + bar); | |
}, 2000); | |
}, 1000); | |
} | |
nested(); // 1 2 | |
/* | |
* @desc in this case the use of the 'var' is useful, because | |
* you can 'escape' the scope | |
*/ | |
function validateUser(user) { | |
try { | |
var result = validate(user); | |
} catch(error) { | |
// the redeclaration of 'result' is for redability purposes | |
// to see which scope is in. | |
var result = 'someting wrong'; | |
} | |
return result; | |
} | |
/* | |
* @desc variable hosting | |
* | |
*/ | |
// variable declarations are hoisted | |
var myVariable = 'outer value'; | |
var fn = function () { | |
alert(myVariable); | |
var myVariable = 'new local value'; | |
}; | |
fn(); // alerts undefined | |
// what the interpreter does | |
var myVariable = 'outer value'; | |
var fn = function () { | |
var myVariable; // declaration | |
alert(myVariable); | |
myVariable = 'new local value'; // initialization | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment