explanation on javascript variables inside a function - javascript

I am learning javascript and came across a topic which mentions that the variables declared inside a function is available anywhere inside the function and javascript puts the variable definition at the top like in the below example:
var functionScope=function(){
for (var i=0; i< 10; i++){//code inside this loop}
return i;
}
console.log(functionScope()); //prints 10
The javascript actually turns the above function to the below:
var functionScope=function(){
var i;
for ( i=0; i< 10; i++){//code inside the for loop}
return i;
}
console.log(functionScope()); //prints 10
Since javascript is interpreted language, it executes line by line. How will it know that it should pull the variable to the top of the function after it has tried accessing the variable. When it tries to access the variable it should tell as undefined right?
Also if I go by the theory that the variables will be placed at the top of the function and can be accessed anywhere then the below code should print 10, but why the below code prints undefined?
var functionScope=function(){
console.log('The value os i is '+i);
var i = 20;
}
console.log(functionScope());
Could someone explain where my understanding is wrong?
One more doubt: Typically in Java, if I had to print the value of i outside the for loop, i would get an error, but in javascript does the variable still accessible outside outside the for loop as in case of fist example where the variable is defined inline inside the for loop. Am i missing something here?

var functionScope=function(){
for (var i=0; i< 10; i++);
return i
}
console.log(functionScope()); //prints 10
This is only a bad indentation. Because of the ; at the end of for, it doesn't includes the return i statement into the loop.
There is the well indented one to help you understand what really happens:
var functionScope=function() {
for (var i=0; i< 10; i++)
/* do nothing */;
return i
}

With var, you tell the JS that the variable is not global, and it'll be aviable only inside the function.
With =, you can set the variable's value.
var i; for (i = 0; ... and for (var i = 0; ... is the same.
In the third example, you don't have i inside the function. In this case, the JS'll try to find it as a global variable, outside the function. If you've set window.i = 1, it'll print The value os i is 1, otherwise it'll generate an error, because i is not defined nowhere.
var i = 0;
var fn = function() {
i = 1; //window.i = 1;
};
console.log(i); //prints 1
var i = 0;
var fn = function() {
var i = 1; //fn.i = 1;
}
console.log(i); //prints 0
var fn = function() {
var i = 1; //fn.i = 1;
}
console.log(i); //ReferenceError: i is not defined
var i;
var fn = function() {
var i = 1; //fn.i = 1;
}
console.log(i) //prints undefined
As Sebastien C. has already told you, your example code dosn't do what you want it to do. for (var i=0; i< 10; i++); means for (var i=0; i< 10; i++) {/*do nothing*/}. If you remove the ;, you'll notece your function will return 0, because the return keyword stops the function, and it return the value, no other operations will be executed, your loop will run only once.
Also, you should use ++i.

Yes Javascript is interpreted and whenever is finds a var declared/undeclared, it declares it and then performs the operations or in technical terms it does var hoisting. So now the variable is declared, but is undefined.
So any operation done on it (other than assignment) will result in its value being undefined only. eg;
{
x++ ;
var x = 10 ;
console.log(x);
}
will print 10. So you can think of it as
{
var x = undefined; \\variable hoisted at beginning of block
x++ ;
x = 10 ;
console.log( x ); \\ x = 10
}

Related

Value of variable with "var" keyword changes after using the same variable in For loop

Can someone explain that why the value of i with the var keyword changes after re-declaring the same variable in a for loop?
For example the value 10 is set to variable i and after setting the condition in for loop i < 40 the value changes to i?
var i = 10;
for (var i = 0; i < 40; i++) {
// code block
}
document.getElementById("demo").innerHTML = i;
<div id="demo"></div>
var statements are scoped to the function they are declared within and the for loop is in the same function as the line immediately before it. (For historical reasons, redeclaring a variable with var doesn't throw an error, it is just silently ignored (although the assignment isn't).)
Use a let statement if you want a variable scoped to the block.
Because in the first part of your loop, you are re-declaring the same var.
To solve this, you must change the name of the first "i" var. For example "j"
And on the first part of your loop, equal "i" to "j" -> var i = j
Here is the snippet
var j = 10;
for (var i = j; i < 40; i++) {
// code block
}
document.getElementById("demo").innerHTML = i;
<div id="demo"></div>

What happens if you put an iteration count of a for loop as a variable?

I want to make a program in javascript in which a person inputted the iteration count for a for loop(they could input x++, or y--), but I don't know if I am using the right method.
Here is my code:
var x = prompt("iteration count")
// x should equal something like, i++, or x--
for(var i = 0; i < 10; x){
document.write(i)
}
But when the code ran the program kept crashing.
Why is it crashing and how do I fix this?
Please Help
you need to parse the int value of x because it's a string and use it to increment i
var x = parseInt(prompt("iteration count"))
for (var i = 0; i < 10; i += x) {
document.write(i)
}
EDIT :
based on the question edit and the comments, you can use eval(), but :
Do not ever use eval!
eval() is a dangerous function, which executes the code it's passed with the privileges of the caller.
So before you use it, read the MDN page and check : eval isnt evil it's just misunderstood
where there's this comment from Spudley :
From a security perspective, eval() is far more dangerous in a server
environment, where code is expected to be fully trusted and hidden
from the end user.
In a browser, the user could eval any code they wanted at any time
simply by opening dev tools, so as a developer you can't get away with
having anything on your client code that could be insecure against
eval anyway.
to test the snippet below, type i++ in the prompt
var x = prompt("iteration count");
for (var i = 0; i < 10; eval(x)) {
console.log(i)
}
an alternative to eval() would be new Function or check the answers here : Programatically setting third statement of for loop
var input = 'i++';//Or whatever condition user passing in
var conditionProgramatically = () => new Function(input)() ;
for (var i = 0; i < 10; conditionProgramatically()) {
console.log(i)
}
For for-loop, third statement will be invoked/executed on every iteration, and hence we set a function call, and in that function, we execute whatever user passing in as you've mentioned i++
That is an endless loop because the variable i never incremented. Try this one.
var x = prompt("iteration count")
for(var i = 0; i < x, i++){
document.write(i)
}
You forgot to increment the index variable, it result to endless loop and maximum stack error, you can also use + for parseInt shorcut.
var x = +prompt("iteration count")
for(var i = 0; i < x;i++){
document.write(i)
}
You have to parse the input value and then make it as a condition to stop iterating after the given value.
var x = parseInt(prompt("iteration count"))
for (var i = 0; i < x; i++) {
document.write(i);
}

Undefined is not an object in Dropdown

I want my code to show the menu by adding a slactive class and change the value of an input from ddown collection. I have some code, which isn't working as console says that on line 9 nor ddown[i], nor slitems[j] are objects, as they're undefined. How to fix this?
var slitems = document.getElementsByClassName('slitem');
ddown = document.getElementsByClassName('ddown');
for(i=0; i<ddown.length; i++) {
ddown[i].addEventListener('click', function(){document.getElementById('sl'+i).classList.add('slactive');valueChange()});
}
function valueChange(){
for(j=0;j<slitems.length;j++){
slitems[j].addEventListener('click', function(){
ddown[i].value = slitems[j].value;
document.getElementById('sl'+i).classList.remove('slactive');
});
}
}
P.S. slitems is a collection of menu elements.
Look, what you are doing has at least two flaws:
1st: when doing this: for(i=0; i < ddown.length; i++) ... you are declaring a global variable named i that, at the end of loop will have the value ddown.length; so, in valueChange, it will always have the same value
2nd: i is set to ddown.length, that is a position that doesn´t exists in the array, hence the error you got.
To fix this, set i as a local variable using var, and pass it as an argument:
var slitems = document.getElementsByClassName('slitem');
ddown = document.getElementsByClassName('ddown');
for(var i=0; i<ddown.length; i++) {
ddown[i].setAttribute("data-index", i);
ddown[i].addEventListener('click', function(e){
var i = e.target.dataset.index;
document.getElementById('sl'+i).classList.add('slactive');valueChange(i)
});
}
function valueChange(i){
for(var j=0;j<slitems.length;j++){
slitems[j].setAttribute("data-index", j);
slitems[j].setAttribute("data-index2", i);
slitems[j].addEventListener('click', function(e){
var j = e.target.dataset.index;
var i = e.target.dataset.index2;
ddown[i].value = slitems[j].value;
document.getElementById('sl'+i).classList.remove('slactive');
});
}
}
EDIT
Changed the code to add the variables used in iterators as node attributes, what should fix the variable scope issue.

Variable declaration necessary in for loop?

What is the difference between:
for (var i=0; i<5; i++) {}
for (i=0; i<5; i++) {}
And is it necessary to include the var keyword?
I understand that the var keyword affects variable scope, but I'm having trouble understanding if it's necessary to include the keyword in for loops.
In the second example, your variable is defined globally, so if you're in the browser environment, you can access it from the window object.
The first one is an equivalent of:
var i;
for (i=0; i<5; i++) {}
as all the variables in javascript are hoisted to the beginning of the scope.
1
for (var i = 0; i < 5; ++i) {
// do stuff
}
2
var i;
for (i = 0; i < 5; ++i) {
// do stuff
}
3
for (i = 0; i < 5; ++i) {
// do stuff
}
1 and 2 are the same.
3 you probably never mean to do — it puts i in the global scope.
I am assuming your are using C#, Java or JavaScript. The short answer is you need the var if "i" has not already been declared. You do not need if it has already been declared.
For example:
var i;
for(i=1;i<=5;i++) {}
Now there may be some implicit variable typing depending on language and IDE, but relying on implicit typing can be difficult to maintain.
Hope this helps, good luck!

Javascript create a list of functions dynamically

I have a piece of JavaScript code that I want to create a list of functions. All the functions will be put in a dictionary d. d["a"] will give me the function function() {console.log("a")} and d["b"] will give me the function function() {console.log("b")} etc. This is my code:
var a = "abcdefghijklmnopqrstuvwxyz1234567890".split("");
var d = {};
for(var l = a.length, i = 0; i < l; i++)
{
d[a[i]] = function(){console.log(a[i])};
}
However, when I run the above code, d["a"] and d["b"] will be the same, they all point to function(){console.log(a[i])}. How to get what I want?
Thanks.
You need to give each instance of the function its own variable:
for(var l = a.length, i = 0; i < l; i++)
{
(function (x) {
d[a[x]] = function(){console.log(a[x])};
})(i)
}
They don't point to the same instance of function(){console.log(a[i])}, instead, you've created a bunch of functions that all use the same reference to i. The value that i points at changes as the for loop executes.
The other answers provided will work, but it involves generating twice as many functions as you need.
function makeLogFunction(whatToLog) {
return function() {
console.log(whatToLog);
}
}
var a = "abcdefghijklmnopqrstuvwxyz1234567890";
var d = {};
for(var l = a.length, i = 0; i < l; i++) {
d[a[i]] = makeLogFunction(a[i]);
}
Here, I have a makeLogFunction that will return a new function that always prints whatToLog. The other answers will generate a new "version" of the makeLogFunction every time the loop executes. For very large sets of data, this is a waste of time and memory.
This approach has added advantages of clarity and reusability. If there's a significant amount of logic happening in your loop, encapsulating it in a named function allows future reviewers to get a sense of what's going on by the name you give to the function. You can also reuse the function in other parts of your application.

Categories

Resources