Skip to content

Instantly share code, notes, and snippets.

@aneurysmjs
Last active February 10, 2023 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aneurysmjs/88f8ec8054c91d918418e3e55faefcd8 to your computer and use it in GitHub Desktop.
Save aneurysmjs/88f8ec8054c91d918418e3e55faefcd8 to your computer and use it in GitHub Desktop.
practical use of 'var' statement
/*
* @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