'const' scope in for loop JavaScript [duplicate] - javascript

This question already has answers here:
Explanation of `let` and block scoping with for loops
(5 answers)
Re-assign/declare a const variable in a JavaScript for-loop and save it more than one time with different values?
(2 answers)
const variable can be redeclared inside while loop even though it should be constant
(1 answer)
Closed last year.
In the code below, is ele available only for an individual iteration of the loop?
for (var i=0; i<3; i++){
const ele = i
console.log(ele)
}
I'm thinking this should be the case, otherwise there will be a
Syntax Error: Identifier 'ele' has already been declared
every time the loop iterates after the very first time.
I could not find a way to confirm this using console.log(), so looking for a concrete answer.
EDIT: To clarify, I understand that ele is valid within the for loop only. My question is specifically if the scope is ' reinstantiated' every iteration of this loop or not. It definitely looks like it, but I haven't heard or read that explicitly anywhere yet.

why do not directly use console.log(i) ?
howei think you should try to use var or let instead of const

Related

`var` and `let` behaviour in arrow functions [duplicate]

This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
Closed 5 years ago.
Why i behaves differently in arrow functions? Is it because var x is being reassigned while let x is being created new for each iteration?
//prints 55555
for(var x = 0; x < 5;x++){
setTimeout(()=>console.log(x),0);
}
//prints 01234
for(let x = 0;x < 5;x++){
setTimeout(()=>console.log(x),0);
}
It has nothing to do with arrow functions. let is block level scope, so each time you enter the body of the loop, you get a new variable.
In your case, the timer function prints differently, because of the closure being created around x.
var provides one variable that all iterations of the loop (and therefore, all timer callbacks) share, hence you get the last value of the variable shared by each timer callback. Remember, the timer callbacks won’t run until your loop is finished and, at that time, x has been incremented to 5.
let gives each timer callback it’s own value because of the block scope. So, even though the timer callbacks don’t run until the loop is finished, each callback has a closure around a differently scoped variable.
let in the loop can re-binds it to each iteration of the loop, making
sure to re-assign it the value from the end of the previous loop
iteration, so it can be used to avoid issue with closures.
Read more here: http://www.jstips.co/en/javascript/keyword-var-vs-let/

Why this code works? (bizarre syntax in javascript) [duplicate]

This question already has answers here:
Using 'let' as a variable name is not throwing any errors in google v8
(3 answers)
Closed 5 years ago.
I found this line of code works:
for(let in [0,1,2]) {console.log('wtfjs');}
but not these:
for(var in [0,1,2]) {console.log('js');}
for(const in [0,1,2]) {console.log('js');}
(Try those on Chrome, Firefox even Edge!)
I'm totally puzzled with it.
Found Another one
for(let of [0,1,2]) {console.log(let);}
Why does this not work?
It appears that let implies the variable name 'let' where var and const do not imply a name. You need a variable or const name in the ones that don't work. Like this:
for(var x in [0,1,2]) {console.log('js');}
for(const y in [0,1,2]) {console.log('js');}

Why do functions defined in a loop all return the same value? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I'm confused by the following JavaScript code. I wrote a loop and defined a function inside the loop, but when I call a function defined in the loop, I only get 10 rather than the index.
Obviously, in the following code I abstracted out stuff that isn't relevant:
objectArray = [];
for (i = 0; i< 10; i++){
objectArray[i] = {};
}
for (i = 0; i< 10; i++){
objectArray[i].get_number = function(){
return i;
}
}
console.log(objectArray[5].get_number()); // returns 10 rather than 5
I always get 10 rather than i as expected.
It's because of JavaScript closure. The method objectArray[i].get_number has direct access to i (not a copy of i). The value of i lives on in memory because each method objectArray[i].get_number still has access to it. There's only one i, and when the loop iterates it, it increases by one. When a method objectArray[i].get_number accesses it, the loop has already run to completion, so it accesses the final value of i.

Why shouldn't I make functions within a loop in Javascript? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
In JavaScript, what are specific reasons why creating functions within a loop can be computationally wasteful?
(2 answers)
Closed 8 years ago.
I checked over my script the other day with JSFiddle and got a warning on one of the lines: Don't make functions within a loop.
for (x = 0; x < 10; x++) {
if (moment(now) > moment(then)) {
doIt(x); // do it now
} else {
timeTillEnd = moment(then) - moment(now);
setTimeout(function () {
doIt(x); // do it later
}, timeTillEnd); // <-- flagged here
}
}
Why shouldn't I make functions within a loop in Javascript?
Also: Could the usage of a function in the particular situation shown here be problematic?
What you are trying to do is probably wrong, the x variable might not be what you expect it to be. See the following link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Creating_closures_in_loops.3A_A_common_mistake
And they are also relatively expensive to create.
Each function comes with the closure of the variables it uses, that is an unnecessary overhead if you are doing "normal imperative programming" and just want to make the code look clearer by defining inner functions for sub-tasks:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Performance_considerations
In your case, it seems that you actually need a function with its closure, since you are deferring some computation, but make sure that you do the proper value capture.
Because it can lead to unexpected closure behaviour (the captured variable will have the value assigned in the last iteration of the loop). You will also get a new instance of the function for each loop which is wasteful of resources.
Modern browsers take a third argument for setTimeout which is the argument to the function. See here. This also gets rid of the problems with closures.

dynamically adding javascript eventlistener doing unexplainable things [duplicate]

This question already has answers here:
Javascript infamous Loop issue? [duplicate]
(5 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 9 years ago.
Currently working on a piece of code that is supposed to add eventlisteners to images on a page in a dynamical way.
var images = document.getElementsByClassName("imageBox");
function imageZoomer(imageName) {
console.log(imageName);
}
for(var i = 0; i < images.length; i++) {
images[i].addEventListener("click", function(){imageZoomer(i)}, false);
}
However the i is showing different values then I expect. At first everything is going wel. It iterates just like it's suppose to do. But on my test page with 2 images the console log reveals '2' at both the images.
This happens because i keeps incrementing and by the time you click an image i is probably images.length - 1. You need a way to save the current i in each handler. You can store that value on each image (images[i].index = i; usually works) and retrieve it later but finding the object is a pain - it'd end up being something like:
images[i].index = i;
images[i].addEventListener("click", function(e){imageZoomer(e.target.index)}, false);
However, I've found the slickest way to do this is using an IIFE (read: iffy - Immediately Invoked Function Expression) to restrict the scope of i to whatever it was when the event was created. That looks something like:
images[i].addEventListener("click", (function(i){return function(){imageZoomer(i)}})(i))
IIFEs are super powerful. Take a look at Ben Alman's post: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

Categories