var sum = 2;
function addFive() {
var sum = sum + 5;
console.log(sum); //why not 7
}
addFive();
Why is it returning NaN instead of 7?
To make things clearer, your code is essentially being read like so:
var sum = 2;
function addFive() {
var sum; // implicitly equal to undefined
sum = sum + 5; // sum = undefined + 5 = NaN
console.log(sum); // NaN
}
addFive();
As you can see, you're redeclaring sum and it is set to undefined. So, when you try and add 2 to undefined you're going to get NaN (Not a Number).
Instead, you can reference your outer sum variable by not redefining it within your function and instead just reassign its value:
var sum = 2;
function addFive() {
sum = sum + 5; // sum = 2 + 5 = 7
console.log(sum); // 7
}
addFive();
You're declaring the variable sum again in the function. This has all to do with scoping in JavaScript.
Take a look at the following article to learn more.
In this case, the local variable (the one that's declared inside the function) gets priority by the JavaScript parser. This behavior's called 'shadowing'. It starts at the innermost scope being executed at the time, and continues until the first match is found, no matter whether there are other variables with the same name in the outer levels or not.
Because you are declared a local variable sum inside the function.
You have to use this.
var sum = 2;
function addFive(){
var sum = this.sum + 5;
console.log(sum);
}
addFive();
In this context, this will refer to the global object (in a browser, window), so the above code is equal to:
var sum = 2;
function addFive(){
var sum = window.sum + 5;
console.log(sum);
}
addFive();
You can read more about this in this SO post or on MDN
Hello fellow good devs,
I am writing a node app and I encountered a counter problem, but this is probably a pure JS problem.
I wrote this test code (instead of my complicated problem) in order to present the issue more clearly.
var func2 = function(i,counter,arrcounter)
{
counter++;
console.log('counter is ' + counter);
arrcounter.push(i);
console.log('arrcounter ' + arrcounter);
}
var looptest = function(){
var counter = 0;
var arrcounter = [];
for (var i = 0 ; i<10 ; i++)
func2(i,counter,arrcounter);
}();
As you can see, I declared var counter = 0 before the for loop, as well an array called arrcounter, and I passed it to func2, func2 is being called at every iteration.
And I got this output:
counter is 1
arrcounter 0
counter is 1
arrcounter 0,1
counter is 1
arrcounter 0,1,2
counter is 1
arrcounter 0,1,2,3
counter is 1
arrcounter 0,1,2,3,4
counter is 1
arrcounter 0,1,2,3,4,5
counter is 1
arrcounter 0,1,2,3,4,5,6
counter is 1
arrcounter 0,1,2,3,4,5,6,7
counter is 1
arrcounter 0,1,2,3,4,5,6,7,8
counter is 1
arrcounter 0,1,2,3,4,5,6,7,8,9
As you can see above, the arrcounter was "incremented" corrected (not exactly the right term for array.push i know), yet the integer counter seems to being passed as 0 at every func2 call.
My question is, both the counter and arrcounter were declared before the for loop,
why then the arrcounter "keeps track" correctly while the counter doesn't? And what's the right way to do for the counter in this case?
In Javascript, primitive types are passed by value. In your case counter is also passed by value and changes made to it will not be reflected back. You push i in arrCounter array which is getting incemented that is why arrCounter array shows correct data. Your counter variable is not a global variable and is passed by value to func2() , so changes made to it in func2() will not be reflected back, that is why it is always passed as 0 only.
If you will increment your counter variable and send its value to Func2(), it will start showing correct results, try the following:
var func2 = function(i,counter,arrcounter)
{
console.log('counter is ' + counter);
arrcounter.push(i);
console.log('arrcounter ' + arrcounter);
}
var looptest = function(){
var arrcounter = [];
var counter = 0;
for (var i = 0 ; i<10 ; i++)
func2(i,counter++,arrcounter);
}();
In javascript variable point to objects. This is what assignments do — they point the lefthand to reference the righthand.
When you pass the variable counter into func2 the argument points to object, in this case a number. When func2 then reassigned the variable counter to a new object it takes the local counter variable and points it at a different number object. This has no effect on the variable counter in looptest. So every iteration of your for loop passes 0 to func2.
When you pass an array, it passes a reference to the array, so the array in func2 is the same object as the array in loopiest'. In 'func2' you don't reassign the variablearr, but rather alter the original object, so the changes are seen in thelooptest. So you see the changes reflected inlooptest`
You can see this clearly in this example:
function test(number, arr) {
// reassign number
number = 10;
// change arr
arr.push(1)
/* try reassigning arr instead for a comparison */
// arr = [1]
}
function start(){
var number = 1
var arr = []
test(number, arr)
// only arr has been changed
console.log(number)
console.log(arr)
}
start()
For a better understanding of which parameters are passed by value and which by reference.
The paramters of a function...
Primitives type are passed by value.
Objects (and Arrays) are passed by reference.
var butImGlobal = 1;
var integerVar = 1;
var stringVar = 'change or not ?';
var array = [0,1];
var obj = {fruit: 'apple'};
function test(byvalInt, byvalTest, byrefArr, byrefObj){
byvalInt = 99999;
byvalTest = 'not change';
byrefArr.push('I\'m new!');
byrefObj.fruit = 'pineapple';
butImGlobal = 'my value is changed, and I can change my type too!';
}
document.getElementById('test').innerHTML = '<b>BEFORE</b><br/>integerVar = ' + integerVar + '<br/>stringVar = ' + stringVar + '<br/>array = ' + array.join(', ') + '<br/>obj.fruit = ' + obj.fruit + '</br>butImGlobal = ' + butImGlobal;
test(integerVar, stringVar, array, obj);
document.getElementById('test').innerHTML = document.getElementById('test').innerHTML +'<br/><br/><b>AFTER</b><br/>integerVar = ' + integerVar + '<br/>stringVar = ' + stringVar + '<br/>array = ' + array.join(', ') + '<br/>obj.fruit = ' + obj.fruit + '</br>butImGlobal = ' + butImGlobal;
<div id="test"></div>
var func2 = function(i,counter,arrcounter)
{
counter++;
console.log('counter is ' + counter);
arrcounter.push(i);
console.log('arrcounter ' + arrcounter);
}
here counter parameter has been passed 0 at first. In javascript primitive type variables are passed by value , not by reference. Here variable counter is of type number and it's a primitive . So when it is passed to func2, a local variable counter will be created for func2. So, it will will increment the local counter parameter of func2 function, not the counter variable you have declared in looptest function
local counter parameter of func2 will be incremented to 1 but the variable counter you have declared in looptest function will remain unchanged.So, every time you wiil be feeding it with 0.
you can try the following :
var looptest = function(){
var counter = 0;
var arrcounter = [];
for (var i = 0 ; i<10 ; i++)
{
counter++;
func2(i,counter,arrcounter);
}
}();
I have a variable equal to number, so I want decrease this variable value every second.
in this code it is print the same number over and over, although I have written
(n--)
var x = setInterval(function() {
var n = 50;
console.log(n--);
}, 1000);
my question how I can decrease it?
You could use a IIFE with a closure about the value. Tha advantage is to use a local variable without polluting the global space.
var x = setInterval(function(n) {
return function() {
console.log(n--);
};
}(100), 1000);
And here is one without the need of a global variable but using IIFE:
var x = setInterval(
(startValue => () => {
console.log(startValue--);
})(100),
1000
);
Checkout this: it will stop when x will equals to zero
var x = 100;
var handler = setInterval(function(){
x--;
console.log(x);
if(x === 0)
clearInterval(handler)
} , 1000)
Your code issue is that you put the -- sign after and It should be before(--n) and It also you have declared var n = 50 inside to loop of setInterval, at this way each time that It's executed n variable always is 50, you should to put this varible at the start of yout code.
var n = 50;
var x = setInterval(function() {
console.log(--n);
}, 1000);
1st if condition:
if (currentQuestionIndex == 2) {
var xvalue = currentscore;
}
2nd if condition: (note: current score increments for every currentQuestionIndex)
if (currentQuestionIndex == 5 && currentscore ==xvalue) {
console.log('thanks for your participation')
}
I want to access the value of xvalue in 1st if condition and reference it in 2nd if condition. Is there any way to store value of a variable and reference it later without regards to if condition
Actually, you can access a variable declared with var inside if statement. A if block (or any block) does not create a new scope: in JavaScript, only a function do that.
This is valid (example from the docs):
if (true) {
var x = 5;
}
console.log(x); // x is 5
This happens because JavaScript interpreter scans your function before executing it, and keep track of all variable declarations (like moving it to the top).
So, the above code is equivalent to (interpreter perspective):
var x;
if (true) {
x = 5;
}
console.log(x); // x is 5
Quoting from MDN:
JavaScript before ECMAScript 2015 does not have block statement scope;
rather, a variable declared within a block is local to the function
(or global scope) that the block resides within.
As pointed, this behavior changes with the introduction of ECMAScript 2015 let.
if (true) {
let x = 5;
}
console.log(x); //x is not defined
So, to use your code as an example, this will run fine:
/* arbitrary values */
var currentQuestionIndex = 2;
var currentscore = 10;
if (currentQuestionIndex == 2) {
var xvalue = currentscore; //declared inside if block
}
if (currentQuestionIndex == 2 && xvalue == 10) { //I can read here
console.log('value of xvalue: ' + xvalue); //can read here too: will print 10
console.log('thanks for your participation')
}
Anyway, just because you can, doesn't mean you should. As a matter of readability and code organization, a recommended practice is to declare your variable at the beginning of your scope (global, if outside any function, or local, if inside a function).
Just define the variable xvalue outside of if statement:
///Just for testing
var currentQuestionIndex = 2
var currentscore = 2
///
var xvalue = 0;
if (currentQuestionIndex == 2) {
xvalue = currentscore;
}
///Just for testing
currentQuestionIndex = 5
currentscore = 4
console.log('xvalue: ' + xvalue)
///
if (currentQuestionIndex == 5 && currentscore == xvalue) {
console.log('thanks for your participation')
///Just for testing
console.log('xvalue: ' + xvalue)
///
}
And read about variable scopes, for example here.
You can set your xvalue variable outside of your if statement.
var xvalue = 0;
or simply:
var xvalue;
This way the variable is always able to be accessed by any other function, even if you haven't given it a value.
Just declare xvalue outside the first if like this:
var xvalue; // decalare it here so it can be accessed by both if statements (probably you'll have to initialize it with something)
if (currentQuestionIndex == 2) {
xvalue = currentscore; // don't redeclare it here so you won't shadow the above one
}
Read more about scopes, variables lifetime and shadowing!
i want to pass one function generated value to another function.
example :
function mainFunc(){
var x = 1;
}
function doMatch(){
var tot = x + 1;
}
only if doMath() Function calls it will calculate total. it shouldn't call mainFunc() Again.
not like this
function mainFunc(){
var x = 1;
return x;
}
function doMatch(){
var tot = mainFunc() + 1;
}
How can i do this. i think if we can make it global variable after it generated from the mainFunc() then every other function can access it.
we cant edit global variable value from function right?
You can define a variable outside the scope of both of these methods that is accessible from each.
function mainFunc(){
window.x = 1;
}
function doMatch(){
var tot = x + 1;
}