JSHint: "Unexpected 'var'" in For Loop [duplicate] - javascript

This question already has answers here:
Why does not JSLint allow "var" in a for loop?
(3 answers)
Closed 3 years ago.
I am running JSHint on my Javascript code to try and clean it up and it is giving me this warning:
#3 Unexpected 'var'.
for (var i = 0; i < self.myArray.length; i++) { // Line 88, Pos 14
Expanding this out, it is this piece of code:
self.myFunction = function() {
for (var i = 0; i < self.myArray.length; i++) {
// Do some stuff
}
};
I have searched the internet and seen many ways to write a for loop. Some use var, some don't, others use let etc.
I can't seem to find any info on how JSHint expects me to construct my for loop. Can anyone enlighten me on some best practice, or what JSHint is looking for?
Thanks! :)

If you use var then it will create the variable as the enclosed function scoped or global scope (if not inside a function).
So always use let in for loop, the scope will be only within for loop.
self.myFunction = function() {
for (let i = 0; i < self.myArray.length; i++) {
// Do some stuff
}
};

Related

Why this Insertion Sort method won't work if I change one VAR for LET in nested loops? [duplicate]

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
What is the difference between "let" and "var"?
(39 answers)
Closed 4 months ago.
I'm currently doing a Javascript bootcamp. Today we were studying Sorting methods. The teacher provided us with "template" not-built-in functions. Another teacher also said that nowadays there's no reason to use VAR anymore to define a variable, that we should always use LET (and const, etc.).
So I copypasted his code in VSCode tu run it and study it. Then I decided to change all the VARs for LETs, and the code stopped working. I tried one by one and discovered it is one in particular (inside a loop that is nested in another loop) that if changed, then the code throws an error. So i would like to understand why is this happening? We've used lots of nested loops and this is the first time it happens.
Here is the code:
// INSERTION SORT
function insertionSort(arr){
let currentVal;
for(let i = 1; i < arr.length; i++){
currentVal = arr[i];
for(**var** j = i - 1; j >= 0 && arr[j] > currentVal; j--) {
arr[j+1] = arr[j]
}
arr[j+1] = currentVal;
}
return arr;
}
let hola = insertionSort([26,54,2,1,9,20,99,76,4]);
console.log(hola);
I wonder if this is related to the scope... If I delete this VAR, the code runs with no issue.... what's going on

Javascript: Uncaught type error: cannot read property innerHTML of undefined [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 1 year ago.
I cannot solve this error , it tells me that my buttons are undefined and cannot read their innerHtml attribute, the convert method is defined in the original code file and i have no problem with it,can you help me , the error comes from the code section below:
var btnsArr = document.getElementsByClassName("btn")
for (var i = 0; i < btnsArr.length; i++) {
btnsArr[i].addEventListener("click", function () {
Convert(btnsArr[i].innerHTML);
return false;
})
} ```
This is an issue of scoping in javascript aka closure inside loop problem. When getting to the function execution at runtime, i has completed its loop and is out of bound for the array.
You need to bound the variable:
for (var i = 0; i < btnsArr.length; i++) {
(function(x) {
btnsArr[x].addEventListener("click", function () {
Convert(btnsArr[x].innerHTML);
return false;
});
})(i)
}
I can see a very common issue in the code, is that your array of elements (btnsArr) is used to define the maximum index for your for. The issue here is that btnsArr.length must be btnsArr.length - 1 instead.
why?
if btnsArr has 3 elements it's range will be from 0 to 2, but your for is expecting from 0 to 3 (because btnsArr.length is 3). Then, probably it is failing in the last array element btnsArr[3] that does not exist.
I hope that it helps at least to cover some exception.

Scope of variable defined in loop initialization in Javascript? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
let keyword in the for loop
(3 answers)
Closed 2 years ago.
Why is the output of the following code :
let nodes = [];
for (let i = 0; i < 5; ++i) {
nodes[i] = () => i;
}
for (let node of nodes) {
console.log(node());
}
is 0 1 2 3 4, while the output of the following code :
let nodes = [];
let i;
for (i = 0; i < 5; ++i) {
nodes[i] = () => i;
}
for (let node of nodes) {
console.log(node());
}
is 5 5 5 5 5?
let variables are scoped the to the block you use it in.
If you use let outside the for block, then you create one variable shared by each function you create (and you change the value of that variable each time you go around the loop).
If you use let inside it, you create a new variable each time you go around the loop, so each function has its own variable with a value that you aren't changing.
How do closure and environment context come into play in this?
They don't really. It's just a matter of if each function closed over the same i or a different i … and you aren't using this.
The type of function you use is irrelevent. You'd get the same effect with a function expression.
Variables declared by let have their scope in the block for which they are defined, as well as in any contained sub-blocks.
In your first code, variable i is declared as local variable during iteration. But in the second code, i is declared as a global variable. So that it prints 5,5,5,5,5
Please refer this link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

Understanding JavaScript scopes [duplicate]

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 5 years ago.
I'm trying to understand how scopes work in JS. Can you tell me if I correct with understanding of this chunk of code:
for(var i = 0; i<5; i++){
setTimeout(function timeoutHandler() {
var i = i;
console.log(i); //undefined
})
}
console.log prints undefined 5 times. So as I understand, when timeoutHandler is executed, it has its own local scope with own i variable. So is that correct that during timeoutHandler execution, the interpreter asks for i variable, finds it declared in local scope and uses this declared variable for assignment? This explains why it is undefined, but I'm not sure I'm fully correct.
Thanks
UPD
I don't need this code to work properly, I just want to understand why it behaves like that in this case
Trying to make sense of it by this example:
for(var i = 0; i<5; i++){
//create a self executing function
(function(iValue){
//in this scope iValue has the i from the loop
setTimeout(function() {
console.log(iValue); //will print the correct i
})
})(i); //pass i in it's current context to the function
}
Or easier with ES6:
Use let instead of var.
Since let is scoped within the block (each run of the loop is it's own block) it will not get another value inside the setTimeout.
for(let i = 0; i<5; i++){
setTimeout(function() {
console.log(i); //will print the correct i
})
}

Putting multiple statements within `for` argument [duplicate]

This question already has answers here:
Multiple counters in Javascript for loop
(3 answers)
Closed 7 years ago.
I wanted to put multiple statements in the initialization statement of a for loop, and I did as follows:
for({var i = 0; var j = 1;}; someCondition; i++){
...
}
But this seems to cause a syntax error. Isn't a single statement replacable with {}? Why didn't it work? Is there a way to put multiple statements in for argument?
You can use { } to create a new block in place of a statement. But a for loop requires a declaration or assignment.
Instead, you can use ,.
for (i = 0, j = 1; someCondition: i++) { ... }
But this seems to cause a syntax error.
Yes, it does.
Isn't a single statement replacable with {}?
No.
Is there a way to put multiple statements in for argument?
Not really.
For this specific case you can set the value of two variables in a single expression with a comma operator.
for(i = 0, j = 1; someCondition; i++){
But it's decidedly non-idiomatic.
Just use a comma to separate them. See here:
for(i = 0, j = 1; i < 5; i++){
console.log(i, j);
}
There's no reason to expect an expression to be replacable by an object.

Categories